对GridView的行加颜色并弹出Kindeditor

前台代码:

<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>

    <script type="text/javascript">

        function tureDelete() {
            if (confirm('真的要删除吗?') == false)
            { return false;}
        }
        function showdiv()
        {
            document.getElementById("show1").style.display = "block";
            document.getElementById("showDiv").style.display = "block";
        }
    </script>
       <link rel="stylesheet" href="Kindeditor/themes/default/default.css" />
 <link rel="stylesheet" href="Kindeditor/plugins/code/prettify.css" />
 <script charset="utf-8" src="Kindeditor/kindeditor.js"></script>
 <script charset="utf-8" src="Kindeditor/lang/zh_CN.js"></script>
 <script charset="utf-8" src="Kindeditor/plugins/code/prettify.js"></script>

    <script>
        KindEditor.ready(function (K) {
            var editor1 = K.create('#content1', {
                cssPath: 'Kindeditor/plugins/code/prettify.css',
                uploadJson: 'Kindeditor/asp.net/upload_json.ashx',
                fileManagerJson: 'Kindeditor/asp.net/file_manager_json.ashx',
                allowFileManager: true,
                afterCreate: function () {
                    var self = this;
                    K.ctrl(document, 13, function () {
                        self.sync();
                        K('form[name=example]')[0].submit();
                    });
                    K.ctrl(self.edit.doc, 13, function () {
                        self.sync();
                        K('form[name=example]')[0].submit();
                    });
                }
            });
            prettyPrint();
        });
 </script>

    <style type="text/css">

        #showDiv {
          position:absolute;
          top:50%;
          left:50%;
          margin-left:-350px;
          margin-top:-250px;
        }
    </style>
</head>
<body>
     <asp:Label ID="Label1" runat="server" Visible="false" Text=""></asp:Label>
    <form id="form1" runat="server">
       
     
      <div  id="show1" style="display:none;background-color: Black;position:absolute; width:100%;height:100%;top:0px;left:0px; opacity:0.3;"></div>
      <div id="showDiv" style="display:none;background-color:bisque;">

              <table>          
            <tr>
                <td>
                    标题
                </td>
                <td>
                    <asp:TextBox ID="txtTitle" runat="server" Width="250px"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td>
                    内容
                </td>
                <td>
                     <textarea id="content1" cols="100" rows="8" style="width:700px;height:500px;visibility:hidden;" runat="server"></textarea>
     
                </td>
            </tr>
            <tr>
                <td>
                    类别
                </td>
                <td>
                    <asp:DropDownList ID="ddlClassName" runat="server">
                    </asp:DropDownList>
                 
                </td>
            </tr>
            <tr>
                <td>
                    用户
                </td>
                <td>
                    <asp:DropDownList ID="ddlUser" runat="server">
                    </asp:DropDownList>
                </td>
            </tr>
            <tr>
              
                <td align="center" colspan="2">
                    <asp:Button ID="btnUpdate" runat="server" Text="保存"  />
                </td>
            </tr>
        </table>
        </div>
     


    <div  >
   
         <table>
             <tr>
                 <td>
                       <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" AllowSorting="True" OnSorting="GridView1_Sorting" OnRowDataBound="GridView1_RowDataBound" ShowFooter="True">
            <Columns>
                <asp:TemplateField HeaderText="选择">
                    <ItemTemplate>
                        <asp:CheckBox ID="ck1" runat="server" />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="标题">
                    <ItemTemplate>
                        <a href='WebForm1.aspx?id=<%#Eval("Id") %>'><%#Eval("NewsTitle") %></a>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="NewsContent" HeaderText="内容" />
                <asp:BoundField DataField="RealName" HeaderText="创建者" SortExpression="RealName" />

         

                <asp:BoundField DataField="CreateTime" DataFormatString="{0:yyyy-mm-dd hh:mm:ss}" HeaderText="创建时间" SortExpression="CreateTime" />
                <asp:BoundField DataField="ClassName" HeaderText="类型" />
                <asp:TemplateField HeaderText="操作">
                    <ItemTemplate>
                        <asp:LinkButton ID="linkbtnEdit" CommandArgument='<%# Eval("Id") %>' runat="server">编辑</asp:LinkButton>
                    <asp:LinkButton ID="linkDelete" CommandArgument='<%# Eval("Id") %>' runat="server">删除</asp:LinkButton>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
                 </td>
             </tr>
             <tr>
                 <td>
                     <asp:LinkButton ID="lbtnFirst" runat="server" OnClick="lbtnFirst_Click">第一页</asp:LinkButton>
                     <asp:LinkButton ID="lbtnProc" runat="server" OnClick="lbtnProc_Click">上一页</asp:LinkButton>
                     <asp:LinkButton ID="lbtnNext" runat="server" OnClick="lbtnNext_Click">下一页</asp:LinkButton>
                     <asp:LinkButton ID="lbtnLast" runat="server" OnClick="lbtnLast_Click">最后一页</asp:LinkButton>
                 &nbsp;&nbsp;&nbsp;&nbsp;
                     <asp:Button ID="Button1" runat="server" Text="删除" OnClick="Button1_Click" OnClientClick="return tureDelete()" />
                     <asp:Button ID="Button2" runat="server" Text="弹出层" OnClick="Button2_Click1"  />
                 </td>
             </tr>
         </table>
   
    </div>
    
    </form>
</body>

 

后台代码:

 public partial class GridView : System.Web.UI.Page
    {
        string constr = "data source=.;initial catalog=News;user id=sa;password=111111;";
        string sql = "select T1.Id,T1.NewsTitle,SUBSTRING(T1.NewsContent,0,20) as NewsContent,T2.RealName,T1.CreateTime,T3.ClassName  from (select ROW_NUMBER() over (order by Id) as rownumber,* from T_News) T1 left join  T_User T2 on T1.NewsCreator=T2.UserId left join  T_NewsClass  T3 on T1.ClassId=T3.ClassId where  rownumber>(@pageIndex-1)*@pageSize and rownumber<=@pageIndex*@pageSize";
        int count;
       
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ViewState["pageIndex"] = 1;
                DataPage(sql);

            }
        }

        private void DataPage(string sql)
        {
            SqlConnection conn = new SqlConnection(constr);
            conn.Open();
            SqlCommand cmd = conn.CreateCommand();
           // string sql = "select T1.Id,T1.NewsTitle,SUBSTRING(T1.NewsContent,0,20) as NewsContent,T2.RealName ,T1.CreateTime,T3.ClassName from T_News1 T1 join T_User T2 on T1.NewsCreator=T2.UserId join T_NewsClass T3 on T1.ClassId=T3.ClassId";
            cmd.Parameters.AddWithValue("@pageSize", 10);
            cmd.Parameters.AddWithValue("@pageIndex", Convert.ToInt32(ViewState["pageIndex"]));
            cmd.CommandText = sql;
            SqlDataAdapter adapter = new SqlDataAdapter(cmd);
            DataTable dt = new DataTable();
            adapter.Fill(dt);

            string sql1 = "select count(*) from T_News";
            cmd.CommandText = sql1;
            int i =Convert.ToInt32(cmd.ExecuteScalar());
            if (i % 10 == 0)
            {
                ViewState["pageCount"] = i / 10;
            }
            else
            { ViewState["pageCount"] = i / 10+1; }
            conn.Close();
            conn.Dispose();

            GridView1.DataSource = dt;
            GridView1.DataBind();
        }

        protected void lbtnFirst_Click(object sender, EventArgs e)
        {
            ViewState["pageIndex"] = 1;
            DataPage(sql);
        }

        protected void lbtnProc_Click(object sender, EventArgs e)
        {
            int i=Convert.ToInt32(ViewState["pageIndex"]) ;
            if (i>1)
            {
                i--;
                ViewState["pageIndex"] = i;
                DataPage(sql);
            }
        }

        protected void lbtnNext_Click(object sender, EventArgs e)
        {
            int i = Convert.ToInt32(ViewState["pageIndex"]);
            if (i <Convert.ToInt32(ViewState["pageCount"]))
            {
                i++;
                ViewState["pageIndex"] = i;
                DataPage(sql);
            }
        }

        protected void lbtnLast_Click(object sender, EventArgs e)
        {
            ViewState["pageIndex"] = ViewState["pageCount"];
            DataPage(sql);
        }

        protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
        {

            if (ViewState["sortExp"] == null)
            {
                Dictionary<string, string> dic = new Dictionary<string, string>();
                dic.Add(e.SortExpression, "ASC");
                ViewState["sortExp"] = dic;
                sql += " Order by " + e.SortExpression + " " + dic[e.SortExpression];
                 DataPage(sql);
            }
            else
            {
                //判断用户本次点击的排序字段是否和上次点击的排序字段一致,如果一致的话,那么就更改此字段的排序规则,如果不是就清除上次的排序字段,添加新的排序字段和规则(这是根据一个字段排序的情况)
                Dictionary<string, string> dic = ViewState["sortExp"] as Dictionary<string, string>;
                if (dic.ContainsKey(e.SortExpression))
                {
                    if (dic[e.SortExpression] == "ASC")
                    {
                        dic[e.SortExpression] = "DESC";
                    }
                    else
                    {
                        dic[e.SortExpression] = "ASC";
                    }
                }
                else//如果不包含的话就生新创建一个
                {
                    //dic.Clear();
                    dic.Add(e.SortExpression, "ASC");
                }
                sql +="  Order by "+ e.SortExpression + " " + dic[e.SortExpression];
                DataPage(sql);
            }
        }

        protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.Header)
            {
                for (int i = 0; i < e.Row.Cells.Count; i++)
                {
                    if (e.Row.Cells[i].Controls.Count > 0)
                    {
                        LinkButton link = e.Row.Cells[i].Controls[0] as LinkButton;
                        string sortexp = link.CommandArgument;
                        if (ViewState["sortExp"] != null)
                        {

                            Dictionary<string, string> dic = ViewState["sortExp"] as Dictionary<string, string>;
                            if (dic.ContainsKey(sortexp))
                            {
                                Literal li = new Literal();
                                if (dic[sortexp] == "ASC")
                                {
                                    li.Text = "↑";
                                }
                                else
                                {
                                    li.Text = "↓";
                                }
                                e.Row.Cells[i].Controls.Add(li);
                            }
                        }
                    }
                }
            }
            //按条件给gridview的行加背景颜色
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                if (e.Row.Cells[3].Text == "肖唯哲")
                {
                    e.Row.BackColor = Color.Red;
                    //根据条件统计当前页的记录数
                    count++;
                }
            }

          
            if (e.Row.RowType == DataControlRowType.Footer)
            {
                e.Row.Cells.RemoveAt(6);
                e.Row.Cells.RemoveAt(5);
                e.Row.Cells.RemoveAt(4);
                e.Row.Cells.RemoveAt(3);
                e.Row.Cells.RemoveAt(2);
                e.Row.Cells.RemoveAt(1);
                e.Row.Cells[0].ColumnSpan = 8;
                e.Row.Cells[0].HorizontalAlign = HorizontalAlign.Right;
                e.Row.Cells[0].Text = string.Format("肖唯哲:{0}", count);
            }
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            string sqlid = string.Empty;
            foreach (GridViewRow row in this.GridView1.Rows)
            {
                CheckBox ck1=row.Cells[0].FindControl("ck1") as CheckBox;
                if (ck1.Checked == true)
                {
                    LinkButton link=row.Cells[6].FindControl("linkbtnEdit") as LinkButton;
                    sqlid +=" "+link.CommandArgument + " ,";
                }
            }

           string  sql1 = "delete from T_News where Id in (" + sqlid.TrimEnd(',')+")";
           int i= DeleteDatas(sql1);
           if (i > 0)
           {
               ClientScript.RegisterStartupScript(this.GetType(), "key", "alert('删除成功!')", true);
                DataPage(sql);
           }
        }

        private int DeleteDatas(string sql1)
        {
            SqlConnection conn = new SqlConnection(constr);
            conn.Open();
            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandText = sql1;
            int num = Convert.ToInt32(cmd.ExecuteNonQuery());
            return num;
            conn.Dispose();
        }

        protected void Button2_Click1(object sender, EventArgs e)
        {
            //Response.Write("<script type='text/javascript'>showdiv()</script>");
            ClientScript.RegisterStartupScript(this.GetType(), "key", "showdiv()", true);
        }

       

    }

 

Kindeditor代码:

 

 /*******************************************************************************
* KindEditor - WYSIWYG HTML Editor for Internet
* Copyright (C) 2006-2013 kindsoft.net
*
* @author Roddy <luolonghao@gmail.com>
* @website http://www.kindsoft.net/
* @licence http://www.kindsoft.net/license.php
* @version 4.1.5 (2013-01-20)
*******************************************************************************/
(function (window, undefined) {
 if (window.KindEditor) {
  return;
 }
if (!window.console) {
 window.console = {};
}
if (!console.log) {
 console.log = function () {};
}
var _VERSION = '4.1.5 (2013-01-20)',
 _ua = navigator.userAgent.toLowerCase(),
 _IE = _ua.indexOf('msie') > -1 && _ua.indexOf('opera') == -1,
 _GECKO = _ua.indexOf('gecko') > -1 && _ua.indexOf('khtml') == -1,
 _WEBKIT = _ua.indexOf('applewebkit') > -1,
 _OPERA = _ua.indexOf('opera') > -1,
 _MOBILE = _ua.indexOf('mobile') > -1,
 _IOS = /ipad|iphone|ipod/.test(_ua),
 _QUIRKS = document.compatMode != 'CSS1Compat',
 _matches = /(?:msie|firefox|webkit|opera)[\/:\s](\d+)/.exec(_ua),
 _V = _matches ? _matches[1] : '0',
 _TIME = new Date().getTime();
function _isArray(val) {
 if (!val) {
  return false;
 }
 return Object.prototype.toString.call(val) === '[object Array]';
}
function _isFunction(val) {
 if (!val) {
  return false;
 }
 return Object.prototype.toString.call(val) === '[object Function]';
}
function _inArray(val, arr) {
 for (var i = 0, len = arr.length; i < len; i++) {
  if (val === arr[i]) {
   return i;
  }
 }
 return -1;
}
function _each(obj, fn) {
 if (_isArray(obj)) {
  for (var i = 0, len = obj.length; i < len; i++) {
   if (fn.call(obj[i], i, obj[i]) === false) {
    break;
   }
  }
 } else {
  for (var key in obj) {
   if (obj.hasOwnProperty(key)) {
    if (fn.call(obj[key], key, obj[key]) === false) {
     break;
    }
   }
  }
 }
}
function _trim(str) {
 return str.replace(/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g, '');
}
function _inString(val, str, delimiter) {
 delimiter = delimiter === undefined ? ',' : delimiter;
 return (delimiter + str + delimiter).indexOf(delimiter + val + delimiter) >= 0;
}
function _addUnit(val, unit) {
 unit = unit || 'px';
 return val && /^\d+$/.test(val) ? val + unit : val;
}
function _removeUnit(val) {
 var match;
 return val && (match = /(\d+)/.exec(val)) ? parseInt(match[1], 10) : 0;
}
function _escape(val) {
 return val.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}
function _unescape(val) {
 return val.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&amp;/g, '&');
}
function _toCamel(str) {
 var arr = str.split('-');
 str = '';
 _each(arr, function(key, val) {
  str += (key > 0) ? val.charAt(0).toUpperCase() + val.substr(1) : val;
 });
 return str;
}
function _toHex(val) {
 function hex(d) {
  var s = parseInt(d, 10).toString(16).toUpperCase();
  return s.length > 1 ? s : '0' + s;
 }
 return val.replace(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/ig,
  function($0, $1, $2, $3) {
   return '#' + hex($1) + hex($2) + hex($3);
  }
 );
}
function _toMap(val, delimiter) {
 delimiter = delimiter === undefined ? ',' : delimiter;
 var map = {}, arr = _isArray(val) ? val : val.split(delimiter), match;
 _each(arr, function(key, val) {
  if ((match = /^(\d+)\.\.(\d+)$/.exec(val))) {
   for (var i = parseInt(match[1], 10); i <= parseInt(match[2], 10); i++) {
    map[i.toString()] = true;
   }
  } else {
   map[val] = true;
  }
 });
 return map;
}
function _toArray(obj, offset) {
 return Array.prototype.slice.call(obj, offset || 0);
}
function _undef(val, defaultVal) {
 return val === undefined ? defaultVal : val;
}
function _invalidUrl(url) {
 return !url || /[<>"]/.test(url);
}
function _addParam(url, param) {
 return url.indexOf('?') >= 0 ? url + '&' + param : url + '?' + param;
}
function _extend(child, parent, proto) {
 if (!proto) {
  proto = parent;
  parent = null;
 }
 var childProto;
 if (parent) {
  var fn = function () {};
  fn.prototype = parent.prototype;
  childProto = new fn();
  _each(proto, function(key, val) {
   childProto[key] = val;
  });
 } else {
  childProto = proto;
 }
 childProto.constructor = child;
 child.prototype = childProto;
 child.parent = parent ? parent.prototype : null;
}
function _json(text) {
 var match;
 if ((match = /\{[\s\S]*\}|\[[\s\S]*\]/.exec(text))) {
  text = match[0];
 }
 var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
 cx.lastIndex = 0;
 if (cx.test(text)) {
  text = text.replace(cx, function (a) {
   return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  });
 }
 if (/^[\],:{}\s]*$/.
 test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
 replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
 replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
  return eval('(' + text + ')');
 }
 throw 'JSON parse error';
}
var _round = Math.round;
var K = {
 DEBUG : false,
 VERSION : _VERSION,
 IE : _IE,
 GECKO : _GECKO,
 WEBKIT : _WEBKIT,
 OPERA : _OPERA,
 V : _V,
 TIME : _TIME,
 each : _each,
 isArray : _isArray,
 isFunction : _isFunction,
 inArray : _inArray,
 inString : _inString,
 trim : _trim,
 addUnit : _addUnit,
 removeUnit : _removeUnit,
 escape : _escape,
 unescape : _unescape,
 toCamel : _toCamel,
 toHex : _toHex,
 toMap : _toMap,
 toArray : _toArray,
 undef : _undef,
 invalidUrl : _invalidUrl,
 addParam : _addParam,
 extend : _extend,
 json : _json
};
var _INLINE_TAG_MAP = _toMap('a,abbr,acronym,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,img,input,ins,kbd,label,map,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'),
 _BLOCK_TAG_MAP = _toMap('address,applet,blockquote,body,center,dd,dir,div,dl,dt,fieldset,form,frameset,h1,h2,h3,h4,h5,h6,head,hr,html,iframe,ins,isindex,li,map,menu,meta,noframes,noscript,object,ol,p,pre,script,style,table,tbody,td,tfoot,th,thead,title,tr,ul'),
 _SINGLE_TAG_MAP = _toMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed'),
 _STYLE_TAG_MAP = _toMap('b,basefont,big,del,em,font,i,s,small,span,strike,strong,sub,sup,u'),
 _CONTROL_TAG_MAP = _toMap('img,table,input,textarea,button'),
 _PRE_TAG_MAP = _toMap('pre,style,script'),
 _NOSPLIT_TAG_MAP = _toMap('html,head,body,td,tr,table,ol,ul,li'),
 _AUTOCLOSE_TAG_MAP = _toMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'),
 _FILL_ATTR_MAP = _toMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'),
 _VALUE_TAG_MAP = _toMap('input,button,textarea,select');
function _getBasePath() {
 var els = document.getElementsByTagName('script'), src;
 for (var i = 0, len = els.length; i < len; i++) {
  src = els[i].src || '';
  if (/kindeditor[\w\-\.]*\.js/.test(src)) {
   return src.substring(0, src.lastIndexOf('/') + 1);
  }
 }
 return '';
}
K.basePath = _getBasePath();
K.options = {
 designMode : true,
 fullscreenMode : false,
 filterMode : true,
 wellFormatMode : true,
 shadowMode : true,
 loadStyleMode : true,
 basePath : K.basePath,
 themesPath : K.basePath + 'themes/',
 langPath : K.basePath + 'lang/',
 pluginsPath : K.basePath + 'plugins/',
 themeType : 'default',
 langType : 'zh_CN',
 urlType : '',
 newlineTag : 'p',
 resizeType : 0,
 syncType : 'form',
 pasteType : 2,
 dialogAlignType : 'page',
 useContextmenu : true,
 fullscreenShortcut : false,
 bodyClass : 'ke-content',
 indentChar : '\t',
 cssPath : '',
 cssData : '',
 minWidth : 650,
 minHeight : 100,
 minChangeSize : 50,
 zIndex : 811213,
 items : [
  'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste',
  'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright',
  'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript',
  'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/',
  'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold',
  'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'multiimage',
  'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak',
  'anchor', 'link', 'unlink', '|', 'about'
 ],
 noDisableItems : ['source', 'fullscreen'],
 colorTable : [
  ['#E53333', '#E56600', '#FF9900', '#64451D', '#DFC5A4', '#FFE500'],
  ['#009900', '#006600', '#99BB00', '#B8D100', '#60D978', '#00D5FF'],
  ['#337FE5', '#003399', '#4C33E5', '#9933E5', '#CC33E5', '#EE33EE'],
  ['#FFFFFF', '#CCCCCC', '#999999', '#666666', '#333333', '#000000']
 ],
 fontSizeTable : ['9px', '10px', '12px', '14px', '16px', '18px', '24px', '32px'],
 htmlTags : {
  font : ['id', 'class', 'color', 'size', 'face', '.background-color'],
  span : [
   'id', 'class', '.color', '.background-color', '.font-size', '.font-family', '.background',
   '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.line-height'
  ],
  div : [
   'id', 'class', 'align', '.border', '.margin', '.padding', '.text-align', '.color',
   '.background-color', '.font-size', '.font-family', '.font-weight', '.background',
   '.font-style', '.text-decoration', '.vertical-align', '.margin-left'
  ],
  table: [
   'id', 'class', 'border', 'cellspacing', 'cellpadding', 'width', 'height', 'align', 'bordercolor',
   '.padding', '.margin', '.border', 'bgcolor', '.text-align', '.color', '.background-color',
   '.font-size', '.font-family', '.font-weight', '.font-style', '.text-decoration', '.background',
   '.width', '.height', '.border-collapse'
  ],
  'td,th': [
   'id', 'class', 'align', 'valign', 'width', 'height', 'colspan', 'rowspan', 'bgcolor',
   '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.font-weight',
   '.font-style', '.text-decoration', '.vertical-align', '.background', '.border'
  ],
  a : ['id', 'class', 'href', 'target', 'name'],
  embed : ['id', 'class', 'src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess'],
  img : ['id', 'class', 'src', 'width', 'height', 'border', 'alt', 'title', 'align', '.width', '.height', '.border'],
  'p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : [
   'id', 'class', 'align', '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.background',
   '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.text-indent', '.margin-left'
  ],
  pre : ['id', 'class'],
  hr : ['id', 'class', '.page-break-after'],
  'br,tbody,tr,strong,b,sub,sup,em,i,u,strike,s,del' : ['id', 'class'],
  iframe : ['id', 'class', 'src', 'frameborder', 'width', 'height', '.width', '.height']
 },
 layout : '<div class="container"><div class="toolbar"></div><div class="edit"></div><div class="statusbar"></div></div>'
};
var _useCapture = false;
var _INPUT_KEY_MAP = _toMap('8,9,13,32,46,48..57,59,61,65..90,106,109..111,188,190..192,219..222');
var _CURSORMOVE_KEY_MAP = _toMap('33..40');
var _CHANGE_KEY_MAP = {};
_each(_INPUT_KEY_MAP, function(key, val) {
 _CHANGE_KEY_MAP[key] = val;
});
_each(_CURSORMOVE_KEY_MAP, function(key, val) {
 _CHANGE_KEY_MAP[key] = val;
});
function _bindEvent(el, type, fn) {
 if (el.addEventListener){
  el.addEventListener(type, fn, _useCapture);
 } else if (el.attachEvent){
  el.attachEvent('on' + type, fn);
 }
}
function _unbindEvent(el, type, fn) {
 if (el.removeEventListener){
  el.removeEventListener(type, fn, _useCapture);
 } else if (el.detachEvent){
  el.detachEvent('on' + type, fn);
 }
}
var _EVENT_PROPS = ('altKey,attrChange,attrName,bubbles,button,cancelable,charCode,clientX,clientY,ctrlKey,currentTarget,' +
 'data,detail,eventPhase,fromElement,handler,keyCode,metaKey,newValue,offsetX,offsetY,originalTarget,pageX,' +
 'pageY,prevValue,relatedNode,relatedTarget,screenX,screenY,shiftKey,srcElement,target,toElement,view,wheelDelta,which').split(',');
function KEvent(el, event) {
 this.init(el, event);
}
_extend(KEvent, {
 init : function(el, event) {
  var self = this, doc = el.ownerDocument || el.document || el;
  self.event = event;
  _each(_EVENT_PROPS, function(key, val) {
   self[val] = event[val];
  });
  if (!self.target) {
   self.target = self.srcElement || doc;
  }
  if (self.target.nodeType === 3) {
   self.target = self.target.parentNode;
  }
  if (!self.relatedTarget && self.fromElement) {
   self.relatedTarget = self.fromElement === self.target ? self.toElement : self.fromElement;
  }
  if (self.pageX == null && self.clientX != null) {
   var d = doc.documentElement, body = doc.body;
   self.pageX = self.clientX + (d && d.scrollLeft || body && body.scrollLeft || 0) - (d && d.clientLeft || body && body.clientLeft || 0);
   self.pageY = self.clientY + (d && d.scrollTop  || body && body.scrollTop  || 0) - (d && d.clientTop  || body && body.clientTop  || 0);
  }
  if (!self.which && ((self.charCode || self.charCode === 0) ? self.charCode : self.keyCode)) {
   self.which = self.charCode || self.keyCode;
  }
  if (!self.metaKey && self.ctrlKey) {
   self.metaKey = self.ctrlKey;
  }
  if (!self.which && self.button !== undefined) {
   self.which = (self.button & 1 ? 1 : (self.button & 2 ? 3 : (self.button & 4 ? 2 : 0)));
  }
  switch (self.which) {
  case 186 :
   self.which = 59;
   break;
  case 187 :
  case 107 :
  case 43 :
   self.which = 61;
   break;
  case 189 :
  case 45 :
   self.which = 109;
   break;
  case 42 :
   self.which = 106;
   break;
  case 47 :
   self.which = 111;
   break;
  case 78 :
   self.which = 110;
   break;
  }
  if (self.which >= 96 && self.which <= 105) {
   self.which -= 48;
  }
 },
 preventDefault : function() {
  var ev = this.event;
  if (ev.preventDefault) {
   ev.preventDefault();
  }
  ev.returnValue = false;
 },
 stopPropagation : function() {
  var ev = this.event;
  if (ev.stopPropagation) {
   ev.stopPropagation();
  }
  ev.cancelBubble = true;
 },
 stop : function() {
  this.preventDefault();
  this.stopPropagation();
 }
});
var _eventExpendo = 'kindeditor_' + _TIME, _eventId = 0, _eventData = {};
function _getId(el) {
 return el[_eventExpendo] || null;
}
function _setId(el) {
 el[_eventExpendo] = ++_eventId;
 return _eventId;
}
function _removeId(el) {
 try {
  delete el[_eventExpendo];
 } catch(e) {
  if (el.removeAttribute) {
   el.removeAttribute(_eventExpendo);
  }
 }
}
function _bind(el, type, fn) {
 if (type.indexOf(',') >= 0) {
  _each(type.split(','), function() {
   _bind(el, this, fn);
  });
  return;
 }
 var id = _getId(el);
 if (!id) {
  id = _setId(el);
 }
 if (_eventData[id] === undefined) {
  _eventData[id] = {};
 }
 var events = _eventData[id][type];
 if (events && events.length > 0) {
  _unbindEvent(el, type, events[0]);
 } else {
  _eventData[id][type] = [];
  _eventData[id].el = el;
 }
 events = _eventData[id][type];
 if (events.length === 0) {
  events[0] = function(e) {
   var kevent = e ? new KEvent(el, e) : undefined;
   _each(events, function(i, event) {
    if (i > 0 && event) {
     event.call(el, kevent);
    }
   });
  };
 }
 if (_inArray(fn, events) < 0) {
  events.push(fn);
 }
 _bindEvent(el, type, events[0]);
}
function _unbind(el, type, fn) {
 if (type && type.indexOf(',') >= 0) {
  _each(type.split(','), function() {
   _unbind(el, this, fn);
  });
  return;
 }
 var id = _getId(el);
 if (!id) {
  return;
 }
 if (type === undefined) {
  if (id in _eventData) {
   _each(_eventData[id], function(key, events) {
    if (key != 'el' && events.length > 0) {
     _unbindEvent(el, key, events[0]);
    }
   });
   delete _eventData[id];
   _removeId(el);
  }
  return;
 }
 if (!_eventData[id]) {
  return;
 }
 var events = _eventData[id][type];
 if (events && events.length > 0) {
  if (fn === undefined) {
   _unbindEvent(el, type, events[0]);
   delete _eventData[id][type];
  } else {
   _each(events, function(i, event) {
    if (i > 0 && event === fn) {
     events.splice(i, 1);
    }
   });
   if (events.length == 1) {
    _unbindEvent(el, type, events[0]);
    delete _eventData[id][type];
   }
  }
  var count = 0;
  _each(_eventData[id], function() {
   count++;
  });
  if (count < 2) {
   delete _eventData[id];
   _removeId(el);
  }
 }
}
function _fire(el, type) {
 if (type.indexOf(',') >= 0) {
  _each(type.split(','), function() {
   _fire(el, this);
  });
  return;
 }
 var id = _getId(el);
 if (!id) {
  return;
 }
 var events = _eventData[id][type];
 if (_eventData[id] && events && events.length > 0) {
  events[0]();
 }
}
function _ctrl(el, key, fn) {
 var self = this;
 key = /^\d{2,}$/.test(key) ? key : key.toUpperCase().charCodeAt(0);
 _bind(el, 'keydown', function(e) {
  if (e.ctrlKey && e.which == key && !e.shiftKey && !e.altKey) {
   fn.call(el);
   e.stop();
  }
 });
}
function _ready(fn) {
 var loaded = false;
 function readyFunc() {
  if (!loaded) {
   loaded = true;
   fn(KindEditor);
  }
 }
 function ieReadyFunc() {
  if (!loaded) {
   try {
    document.documentElement.doScroll('left');
   } catch(e) {
    setTimeout(ieReadyFunc, 100);
    return;
   }
   readyFunc();
  }
 }
 function ieReadyStateFunc() {
  if (document.readyState === 'complete') {
   readyFunc();
  }
 }
 if (document.addEventListener) {
  _bind(document, 'DOMContentLoaded', readyFunc);
 } else if (document.attachEvent) {
  _bind(document, 'readystatechange', ieReadyStateFunc);
  var toplevel = false;
  try {
   toplevel = window.frameElement == null;
  } catch(e) {}
  if (document.documentElement.doScroll && toplevel) {
   ieReadyFunc();
  }
 }
 _bind(window, 'load', readyFunc);
}
if (_IE) {
 window.attachEvent('onunload', function() {
  _each(_eventData, function(key, events) {
   if (events.el) {
    _unbind(events.el);
   }
  });
 });
}
K.ctrl = _ctrl;
K.ready = _ready;
function _getCssList(css) {
 var list = {},
  reg = /\s*([\w\-]+)\s*:([^;]*)(;|$)/g,
  match;
 while ((match = reg.exec(css))) {
  var key = _trim(match[1].toLowerCase()),
   val = _trim(_toHex(match[2]));
  list[key] = val;
 }
 return list;
}
function _getAttrList(tag) {
 var list = {},
  reg = /\s+(?:([\w\-:]+)|(?:([\w\-:]+)=([^\s"'<>]+))|(?:([\w\-:"]+)="([^"]*)")|(?:([\w\-:"]+)='([^']*)'))(?=(?:\s|\/|>)+)/g,
  match;
 while ((match = reg.exec(tag))) {
  var key = (match[1] || match[2] || match[4] || match[6]).toLowerCase(),
   val = (match[2] ? match[3] : (match[4] ? match[5] : match[7])) || '';
  list[key] = val;
 }
 return list;
}
function _addClassToTag(tag, className) {
 if (/\s+class\s*=/.test(tag)) {
  tag = tag.replace(/(\s+class=["']?)([^"']*)(["']?[\s>])/, function($0, $1, $2, $3) {
   if ((' ' + $2 + ' ').indexOf(' ' + className + ' ') < 0) {
    return $2 === '' ? $1 + className + $3 : $1 + $2 + ' ' + className + $3;
   } else {
    return $0;
   }
  });
 } else {
  tag = tag.substr(0, tag.length - 1) + ' class="' + className + '">';
 }
 return tag;
}
function _formatCss(css) {
 var str = '';
 _each(_getCssList(css), function(key, val) {
  str += key + ':' + val + ';';
 });
 return str;
}
function _formatUrl(url, mode, host, pathname) {
 mode = _undef(mode, '').toLowerCase();
 if (url.substr(0, 5) != 'data:') {
  url = url.replace(/([^:])\/\//g, '$1/');
 }
 if (_inArray(mode, ['absolute', 'relative', 'domain']) < 0) {
  return url;
 }
 host = host || location.protocol + '//' + location.host;
 if (pathname === undefined) {
  var m = location.pathname.match(/^(\/.*)\//);
  pathname = m ? m[1] : '';
 }
 var match;
 if ((match = /^(\w+:\/\/[^\/]*)/.exec(url))) {
  if (match[1] !== host) {
   return url;
  }
 } else if (/^\w+:/.test(url)) {
  return url;
 }
 function getRealPath(path) {
  var parts = path.split('/'), paths = [];
  for (var i = 0, len = parts.length; i < len; i++) {
   var part = parts[i];
   if (part == '..') {
    if (paths.length > 0) {
     paths.pop();
    }
   } else if (part !== '' && part != '.') {
    paths.push(part);
   }
  }
  return '/' + paths.join('/');
 }
 if (/^\//.test(url)) {
  url = host + getRealPath(url.substr(1));
 } else if (!/^\w+:\/\//.test(url)) {
  url = host + getRealPath(pathname + '/' + url);
 }
 function getRelativePath(path, depth) {
  if (url.substr(0, path.length) === path) {
   var arr = [];
   for (var i = 0; i < depth; i++) {
    arr.push('..');
   }
   var prefix = '.';
   if (arr.length > 0) {
    prefix += '/' + arr.join('/');
   }
   if (pathname == '/') {
    prefix += '/';
   }
   return prefix + url.substr(path.length);
  } else {
   if ((match = /^(.*)\//.exec(path))) {
    return getRelativePath(match[1], ++depth);
   }
  }
 }
 if (mode === 'relative') {
  url = getRelativePath(host + pathname, 0).substr(2);
 } else if (mode === 'absolute') {
  if (url.substr(0, host.length) === host) {
   url = url.substr(host.length);
  }
 }
 return url;
}
function _formatHtml(html, htmlTags, urlType, wellFormatted, indentChar) {
 urlType = urlType || '';
 wellFormatted = _undef(wellFormatted, false);
 indentChar = _undef(indentChar, '\t');
 var fontSizeList = 'xx-small,x-small,small,medium,large,x-large,xx-large'.split(',');
 html = html.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/ig, function($0, $1, $2, $3) {
  return $1 + $2.replace(/<(?:br|br\s[^>]*)>/ig, '\n') + $3;
 });
 html = html.replace(/<(?:br|br\s[^>]*)\s*\/?>\s*<\/p>/ig, '</p>');
 html = html.replace(/(<(?:p|p\s[^>]*)>)\s*(<\/p>)/ig, '$1<br />$2');
 html = html.replace(/\u200B/g, '');
 html = html.replace(/\u00A9/g, '&copy;');
 var htmlTagMap = {};
 if (htmlTags) {
  _each(htmlTags, function(key, val) {
   var arr = key.split(',');
   for (var i = 0, len = arr.length; i < len; i++) {
    htmlTagMap[arr[i]] = _toMap(val);
   }
  });
  if (!htmlTagMap.script) {
   html = html.replace(/(<(?:script|script\s[^>]*)>)([\s\S]*?)(<\/script>)/ig, '');
  }
  if (!htmlTagMap.style) {
   html = html.replace(/(<(?:style|style\s[^>]*)>)([\s\S]*?)(<\/style>)/ig, '');
  }
 }
 var re = /([ \t\n\r]*)<(\/)?([\w\-:]+)((?:\s+|(?:\s+[\w\-:]+)|(?:\s+[\w\-:]+=[^\s"'<>]+)|(?:\s+[\w\-:"]+="[^"]*")|(?:\s+[\w\-:"]+='[^']*'))*)(\/)?>([ \t\n\r]*)/g;
 var tagStack = [];
 html = html.replace(re, function($0, $1, $2, $3, $4, $5, $6) {
  var full = $0,
   startNewline = $1 || '',
   startSlash = $2 || '',
   tagName = $3.toLowerCase(),
   attr = $4 || '',
   endSlash = $5 ? ' ' + $5 : '',
   endNewline = $6 || '';
  if (htmlTags && !htmlTagMap[tagName]) {
   return '';
  }
  if (endSlash === '' && _SINGLE_TAG_MAP[tagName]) {
   endSlash = ' /';
  }
  if (_INLINE_TAG_MAP[tagName]) {
   if (startNewline) {
    startNewline = ' ';
   }
   if (endNewline) {
    endNewline = ' ';
   }
  }
  if (_PRE_TAG_MAP[tagName]) {
   if (startSlash) {
    endNewline = '\n';
   } else {
    startNewline = '\n';
   }
  }
  if (wellFormatted && tagName == 'br') {
   endNewline = '\n';
  }
  if (_BLOCK_TAG_MAP[tagName] && !_PRE_TAG_MAP[tagName]) {
   if (wellFormatted) {
    if (startSlash && tagStack.length > 0 && tagStack[tagStack.length - 1] === tagName) {
     tagStack.pop();
    } else {
     tagStack.push(tagName);
    }
    startNewline = '\n';
    endNewline = '\n';
    for (var i = 0, len = startSlash ? tagStack.length : tagStack.length - 1; i < len; i++) {
     startNewline += indentChar;
     if (!startSlash) {
      endNewline += indentChar;
     }
    }
    if (endSlash) {
     tagStack.pop();
    } else if (!startSlash) {
     endNewline += indentChar;
    }
   } else {
    startNewline = endNewline = '';
   }
  }
  if (attr !== '') {
   var attrMap = _getAttrList(full);
   if (tagName === 'font') {
    var fontStyleMap = {}, fontStyle = '';
    _each(attrMap, function(key, val) {
     if (key === 'color') {
      fontStyleMap.color = val;
      delete attrMap[key];
     }
     if (key === 'size') {
      fontStyleMap['font-size'] = fontSizeList[parseInt(val, 10) - 1] || '';
      delete attrMap[key];
     }
     if (key === 'face') {
      fontStyleMap['font-family'] = val;
      delete attrMap[key];
     }
     if (key === 'style') {
      fontStyle = val;
     }
    });
    if (fontStyle && !/;$/.test(fontStyle)) {
     fontStyle += ';';
    }
    _each(fontStyleMap, function(key, val) {
     if (val === '') {
      return;
     }
     if (/\s/.test(val)) {
      val = "'" + val + "'";
     }
     fontStyle += key + ':' + val + ';';
    });
    attrMap.style = fontStyle;
   }
   _each(attrMap, function(key, val) {
    if (_FILL_ATTR_MAP[key]) {
     attrMap[key] = key;
    }
    if (_inArray(key, ['src', 'href']) >= 0) {
     attrMap[key] = _formatUrl(val, urlType);
    }
    if (htmlTags && key !== 'style' && !htmlTagMap[tagName]['*'] && !htmlTagMap[tagName][key] ||
     tagName === 'body' && key === 'contenteditable' ||
     /^kindeditor_\d+$/.test(key)) {
     delete attrMap[key];
    }
    if (key === 'style' && val !== '') {
     var styleMap = _getCssList(val);
     _each(styleMap, function(k, v) {
      if (htmlTags && !htmlTagMap[tagName].style && !htmlTagMap[tagName]['.' + k]) {
       delete styleMap[k];
      }
     });
     var style = '';
     _each(styleMap, function(k, v) {
      style += k + ':' + v + ';';
     });
     attrMap.style = style;
    }
   });
   attr = '';
   _each(attrMap, function(key, val) {
    if (key === 'style' && val === '') {
     return;
    }
    val = val.replace(/"/g, '&quot;');
    attr += ' ' + key + '="' + val + '"';
   });
  }
  if (tagName === 'font') {
   tagName = 'span';
  }
  return startNewline + '<' + startSlash + tagName + attr + endSlash + '>' + endNewline;
 });
 html = html.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/ig, function($0, $1, $2, $3) {
  return $1 + $2.replace(/\n/g, '<span id="__kindeditor_pre_newline__">\n') + $3;
 });
 html = html.replace(/\n\s*\n/g, '\n');
 html = html.replace(/<span id="__kindeditor_pre_newline__">\n/g, '\n');
 return _trim(html);
}
function _clearMsWord(html, htmlTags) {
 html = html.replace(/<meta[\s\S]*?>/ig, '')
  .replace(/<![\s\S]*?>/ig, '')
  .replace(/<style[^>]*>[\s\S]*?<\/style>/ig, '')
  .replace(/<script[^>]*>[\s\S]*?<\/script>/ig, '')
  .replace(/<w:[^>]+>[\s\S]*?<\/w:[^>]+>/ig, '')
  .replace(/<o:[^>]+>[\s\S]*?<\/o:[^>]+>/ig, '')
  .replace(/<xml>[\s\S]*?<\/xml>/ig, '')
  .replace(/<(?:table|td)[^>]*>/ig, function(full) {
   return full.replace(/border-bottom:([#\w\s]+)/ig, 'border:$1');
  });
 return _formatHtml(html, htmlTags);
}
function _mediaType(src) {
 if (/\.(rm|rmvb)(\?|$)/i.test(src)) {
  return 'audio/x-pn-realaudio-plugin';
 }
 if (/\.(swf|flv)(\?|$)/i.test(src)) {
  return 'application/x-shockwave-flash';
 }
 return 'video/x-ms-asf-plugin';
}
function _mediaClass(type) {
 if (/realaudio/i.test(type)) {
  return 'ke-rm';
 }
 if (/flash/i.test(type)) {
  return 'ke-flash';
 }
 return 'ke-media';
}
function _mediaAttrs(srcTag) {
 return _getAttrList(unescape(srcTag));
}
function _mediaEmbed(attrs) {
 var html = '<embed ';
 _each(attrs, function(key, val) {
  html += key + '="' + val + '" ';
 });
 html += '/>';
 return html;
}
function _mediaImg(blankPath, attrs) {
 var width = attrs.width,
  height = attrs.height,
  type = attrs.type || _mediaType(attrs.src),
  srcTag = _mediaEmbed(attrs),
  style = '';
 if (width > 0) {
  style += 'width:' + width + 'px;';
 }
 if (height > 0) {
  style += 'height:' + height + 'px;';
 }
 var html = '<img class="' + _mediaClass(type) + '" src="' + blankPath + '" ';
 if (style !== '') {
  html += 'style="' + style + '" ';
 }
 html += 'data-ke-tag="' + escape(srcTag) + '" alt="" />';
 return html;
}
function _tmpl(str, data) {
 var fn = new Function("obj",
  "var p=[],print=function(){p.push.apply(p,arguments);};" +
  "with(obj){p.push('" +
  str.replace(/[\r\t\n]/g, " ")
   .split("<%").join("\t")
   .replace(/((^|%>)[^\t]*)'/g, "$1\r")
   .replace(/\t=(.*?)%>/g, "',$1,'")
   .split("\t").join("');")
   .split("%>").join("p.push('")
   .split("\r").join("\\'") + "');}return p.join('');");
 return data ? fn(data) : fn;
}
K.formatUrl = _formatUrl;
K.formatHtml = _formatHtml;
K.getCssList = _getCssList;
K.getAttrList = _getAttrList;
K.mediaType = _mediaType;
K.mediaAttrs = _mediaAttrs;
K.mediaEmbed = _mediaEmbed;
K.mediaImg = _mediaImg;
K.clearMsWord = _clearMsWord;
K.tmpl = _tmpl;
function _contains(nodeA, nodeB) {
 if (nodeA.nodeType == 9 && nodeB.nodeType != 9) {
  return true;
 }
 while ((nodeB = nodeB.parentNode)) {
  if (nodeB == nodeA) {
   return true;
  }
 }
 return false;
}
var _getSetAttrDiv = document.createElement('div');
_getSetAttrDiv.setAttribute('className', 't');
var _GET_SET_ATTRIBUTE = _getSetAttrDiv.className !== 't';
function _getAttr(el, key) {
 key = key.toLowerCase();
 var val = null;
 if (!_GET_SET_ATTRIBUTE && el.nodeName.toLowerCase() != 'script') {
  var div = el.ownerDocument.createElement('div');
  div.appendChild(el.cloneNode(false));
  var list = _getAttrList(_unescape(div.innerHTML));
  if (key in list) {
   val = list[key];
  }
 } else {
  try {
   val = el.getAttribute(key, 2);
  } catch(e) {
   val = el.getAttribute(key, 1);
  }
 }
 if (key === 'style' && val !== null) {
  val = _formatCss(val);
 }
 return val;
}
function _queryAll(expr, root) {
 var exprList = expr.split(',');
 if (exprList.length > 1) {
  var mergedResults = [];
  _each(exprList, function() {
   _each(_queryAll(this, root), function() {
    if (_inArray(this, mergedResults) < 0) {
     mergedResults.push(this);
    }
   });
  });
  return mergedResults;
 }
 root = root || document;
 function escape(str) {
  if (typeof str != 'string') {
   return str;
  }
  return str.replace(/([^\w\-])/g, '\\$1');
 }
 function stripslashes(str) {
  return str.replace(/\\/g, '');
 }
 function cmpTag(tagA, tagB) {
  return tagA === '*' || tagA.toLowerCase() === escape(tagB.toLowerCase());
 }
 function byId(id, tag, root) {
  var arr = [],
   doc = root.ownerDocument || root,
   el = doc.getElementById(stripslashes(id));
  if (el) {
   if (cmpTag(tag, el.nodeName) && _contains(root, el)) {
    arr.push(el);
   }
  }
  return arr;
 }
 function byClass(className, tag, root) {
  var doc = root.ownerDocument || root, arr = [], els, i, len, el;
  if (root.getElementsByClassName) {
   els = root.getElementsByClassName(stripslashes(className));
   for (i = 0, len = els.length; i < len; i++) {
    el = els[i];
    if (cmpTag(tag, el.nodeName)) {
     arr.push(el);
    }
   }
  } else if (doc.querySelectorAll) {
   els = doc.querySelectorAll((root.nodeName !== '#document' ? root.nodeName + ' ' : '') + tag + '.' + className);
   for (i = 0, len = els.length; i < len; i++) {
    el = els[i];
    if (_contains(root, el)) {
     arr.push(el);
    }
   }
  } else {
   els = root.getElementsByTagName(tag);
   className = ' ' + className + ' ';
   for (i = 0, len = els.length; i < len; i++) {
    el = els[i];
    if (el.nodeType == 1) {
     var cls = el.className;
     if (cls && (' ' + cls + ' ').indexOf(className) > -1) {
      arr.push(el);
     }
    }
   }
  }
  return arr;
 }
 function byName(name, tag, root) {
  var arr = [], doc = root.ownerDocument || root,
   els = doc.getElementsByName(stripslashes(name)), el;
  for (var i = 0, len = els.length; i < len; i++) {
   el = els[i];
   if (cmpTag(tag, el.nodeName) && _contains(root, el)) {
    if (el.getAttributeNode('name')) {
     arr.push(el);
    }
   }
  }
  return arr;
 }
 function byAttr(key, val, tag, root) {
  var arr = [], els = root.getElementsByTagName(tag), el;
  for (var i = 0, len = els.length; i < len; i++) {
   el = els[i];
   if (el.nodeType == 1) {
    if (val === null) {
     if (_getAttr(el, key) !== null) {
      arr.push(el);
     }
    } else {
     if (val === escape(_getAttr(el, key))) {
      arr.push(el);
     }
    }
   }
  }
  return arr;
 }
 function select(expr, root) {
  var arr = [], matches;
  matches = /^((?:\\.|[^.#\s\[<>])+)/.exec(expr);
  var tag = matches ? matches[1] : '*';
  if ((matches = /#((?:[\w\-]|\\.)+)$/.exec(expr))) {
   arr = byId(matches[1], tag, root);
  } else if ((matches = /\.((?:[\w\-]|\\.)+)$/.exec(expr))) {
   arr = byClass(matches[1], tag, root);
  } else if ((matches = /\[((?:[\w\-]|\\.)+)\]/.exec(expr))) {
   arr = byAttr(matches[1].toLowerCase(), null, tag, root);
  } else if ((matches = /\[((?:[\w\-]|\\.)+)\s*=\s*['"]?((?:\\.|[^'"]+)+)['"]?\]/.exec(expr))) {
   var key = matches[1].toLowerCase(), val = matches[2];
   if (key === 'id') {
    arr = byId(val, tag, root);
   } else if (key === 'class') {
    arr = byClass(val, tag, root);
   } else if (key === 'name') {
    arr = byName(val, tag, root);
   } else {
    arr = byAttr(key, val, tag, root);
   }
  } else {
   var els = root.getElementsByTagName(tag), el;
   for (var i = 0, len = els.length; i < len; i++) {
    el = els[i];
    if (el.nodeType == 1) {
     arr.push(el);
    }
   }
  }
  return arr;
 }
 var parts = [], arr, re = /((?:\\.|[^\s>])+|[\s>])/g;
 while ((arr = re.exec(expr))) {
  if (arr[1] !== ' ') {
   parts.push(arr[1]);
  }
 }
 var results = [];
 if (parts.length == 1) {
  return select(parts[0], root);
 }
 var isChild = false, part, els, subResults, val, v, i, j, k, length, len, l;
 for (i = 0, lenth = parts.length; i < lenth; i++) {
  part = parts[i];
  if (part === '>') {
   isChild = true;
   continue;
  }
  if (i > 0) {
   els = [];
   for (j = 0, len = results.length; j < len; j++) {
    val = results[j];
    subResults = select(part, val);
    for (k = 0, l = subResults.length; k < l; k++) {
     v = subResults[k];
     if (isChild) {
      if (val === v.parentNode) {
       els.push(v);
      }
     } else {
      els.push(v);
     }
    }
   }
   results = els;
  } else {
   results = select(part, root);
  }
  if (results.length === 0) {
   return [];
  }
 }
 return results;
}
function _query(expr, root) {
 var arr = _queryAll(expr, root);
 return arr.length > 0 ? arr[0] : null;
}
K.query = _query;
K.queryAll = _queryAll;
function _get(val) {
 return K(val)[0];
}
function _getDoc(node) {
 if (!node) {
  return document;
 }
 return node.ownerDocument || node.document || node;
}
function _getWin(node) {
 if (!node) {
  return window;
 }
 var doc = _getDoc(node);
 return doc.parentWindow || doc.defaultView;
}
function _setHtml(el, html) {
 if (el.nodeType != 1) {
  return;
 }
 var doc = _getDoc(el);
 try {
  el.innerHTML = '<img id="__kindeditor_temp_tag__" width="0" height="0" style="display:none;" />' + html;
  var temp = doc.getElementById('__kindeditor_temp_tag__');
  temp.parentNode.removeChild(temp);
 } catch(e) {
  K(el).empty();
  K('@' + html, doc).each(function() {
   el.appendChild(this);
  });
 }
}
function _hasClass(el, cls) {
 return _inString(cls, el.className, ' ');
}
function _setAttr(el, key, val) {
 if (_IE && _V < 8 && key.toLowerCase() == 'class') {
  key = 'className';
 }
 el.setAttribute(key, '' + val);
}
function _removeAttr(el, key) {
 if (_IE && _V < 8 && key.toLowerCase() == 'class') {
  key = 'className';
 }
 _setAttr(el, key, '');
 el.removeAttribute(key);
}
function _getNodeName(node) {
 if (!node || !node.nodeName) {
  return '';
 }
 return node.nodeName.toLowerCase();
}
function _computedCss(el, key) {
 var self = this, win = _getWin(el), camelKey = _toCamel(key), val = '';
 if (win.getComputedStyle) {
  var style = win.getComputedStyle(el, null);
  val = style[camelKey] || style.getPropertyValue(key) || el.style[camelKey];
 } else if (el.currentStyle) {
  val = el.currentStyle[camelKey] || el.style[camelKey];
 }
 return val;
}
function _hasVal(node) {
 return !!_VALUE_TAG_MAP[_getNodeName(node)];
}
function _docElement(doc) {
 doc = doc || document;
 return _QUIRKS ? doc.body : doc.documentElement;
}
function _docHeight(doc) {
 var el = _docElement(doc);
 return Math.max(el.scrollHeight, el.clientHeight);
}
function _docWidth(doc) {
 var el = _docElement(doc);
 return Math.max(el.scrollWidth, el.clientWidth);
}
function _getScrollPos(doc) {
 doc = doc || document;
 var x, y;
 if (_IE || _OPERA) {
  x = _docElement(doc).scrollLeft;
  y = _docElement(doc).scrollTop;
 } else {
  x = _getWin(doc).scrollX;
  y = _getWin(doc).scrollY;
 }
 return {x : x, y : y};
}
function KNode(node) {
 this.init(node);
}
_extend(KNode, {
 init : function(node) {
  var self = this;
  node = _isArray(node) ? node : [node];
  var length = 0;
  for (var i = 0, len = node.length; i < len; i++) {
   if (node[i]) {
    self[i] = node[i].constructor === KNode ? node[i][0] : node[i];
    length++;
   }
  }
  self.length = length;
  self.doc = _getDoc(self[0]);
  self.name = _getNodeName(self[0]);
  self.type = self.length > 0 ? self[0].nodeType : null;
  self.win = _getWin(self[0]);
 },
 each : function(fn) {
  var self = this;
  for (var i = 0; i < self.length; i++) {
   if (fn.call(self[i], i, self[i]) === false) {
    return self;
   }
  }
  return self;
 },
 bind : function(type, fn) {
  this.each(function() {
   _bind(this, type, fn);
  });
  return this;
 },
 unbind : function(type, fn) {
  this.each(function() {
   _unbind(this, type, fn);
  });
  return this;
 },
 fire : function(type) {
  if (this.length < 1) {
   return this;
  }
  _fire(this[0], type);
  return this;
 },
 hasAttr : function(key) {
  if (this.length < 1) {
   return false;
  }
  return !!_getAttr(this[0], key);
 },
 attr : function(key, val) {
  var self = this;
  if (key === undefined) {
   return _getAttrList(self.outer());
  }
  if (typeof key === 'object') {
   _each(key, function(k, v) {
    self.attr(k, v);
   });
   return self;
  }
  if (val === undefined) {
   val = self.length < 1 ? null : _getAttr(self[0], key);
   return val === null ? '' : val;
  }
  self.each(function() {
   _setAttr(this, key, val);
  });
  return self;
 },
 removeAttr : function(key) {
  this.each(function() {
   _removeAttr(this, key);
  });
  return this;
 },
 get : function(i) {
  if (this.length < 1) {
   return null;
  }
  return this[i || 0];
 },
 eq : function(i) {
  if (this.length < 1) {
   return null;
  }
  return this[i] ? new KNode(this[i]) : null;
 },
 hasClass : function(cls) {
  if (this.length < 1) {
   return false;
  }
  return _hasClass(this[0], cls);
 },
 addClass : function(cls) {
  this.each(function() {
   if (!_hasClass(this, cls)) {
    this.className = _trim(this.className + ' ' + cls);
   }
  });
  return this;
 },
 removeClass : function(cls) {
  this.each(function() {
   if (_hasClass(this, cls)) {
    this.className = _trim(this.className.replace(new RegExp('(^|\\s)' + cls + '(\\s|$)'), ' '));
   }
  });
  return this;
 },
 html : function(val) {
  var self = this;
  if (val === undefined) {
   if (self.length < 1 || self.type != 1) {
    return '';
   }
   return _formatHtml(self[0].innerHTML);
  }
  self.each(function() {
   _setHtml(this, val);
  });
  return self;
 },
 text : function() {
  var self = this;
  if (self.length < 1) {
   return '';
  }
  return _IE ? self[0].innerText : self[0].textContent;
 },
 hasVal : function() {
  if (this.length < 1) {
   return false;
  }
  return _hasVal(this[0]);
 },
 val : function(val) {
  var self = this;
  if (val === undefined) {
   if (self.length < 1) {
    return '';
   }
   return self.hasVal() ? self[0].value : self.attr('value');
  } else {
   self.each(function() {
    if (_hasVal(this)) {
     this.value = val;
    } else {
     _setAttr(this, 'value' , val);
    }
   });
   return self;
  }
 },
 css : function(key, val) {
  var self = this;
  if (key === undefined) {
   return _getCssList(self.attr('style'));
  }
  if (typeof key === 'object') {
   _each(key, function(k, v) {
    self.css(k, v);
   });
   return self;
  }
  if (val === undefined) {
   if (self.length < 1) {
    return '';
   }
   return self[0].style[_toCamel(key)] || _computedCss(self[0], key) || '';
  }
  self.each(function() {
   this.style[_toCamel(key)] = val;
  });
  return self;
 },
 width : function(val) {
  var self = this;
  if (val === undefined) {
   if (self.length < 1) {
    return 0;
   }
   return self[0].offsetWidth;
  }
  return self.css('width', _addUnit(val));
 },
 height : function(val) {
  var self = this;
  if (val === undefined) {
   if (self.length < 1) {
    return 0;
   }
   return self[0].offsetHeight;
  }
  return self.css('height', _addUnit(val));
 },
 opacity : function(val) {
  this.each(function() {
   if (this.style.opacity === undefined) {
    this.style.filter = val == 1 ? '' : 'alpha(opacity=' + (val * 100) + ')';
   } else {
    this.style.opacity = val == 1 ? '' : val;
   }
  });
  return this;
 },
 data : function(key, val) {
  var self = this;
  key = 'kindeditor_data_' + key;
  if (val === undefined) {
   if (self.length < 1) {
    return null;
   }
   return self[0][key];
  }
  this.each(function() {
   this[key] = val;
  });
  return self;
 },
 pos : function() {
  var self = this, node = self[0], x = 0, y = 0;
  if (node) {
   if (node.getBoundingClientRect) {
    var box = node.getBoundingClientRect(),
     pos = _getScrollPos(self.doc);
    x = box.left + pos.x;
    y = box.top + pos.y;
   } else {
    while (node) {
     x += node.offsetLeft;
     y += node.offsetTop;
     node = node.offsetParent;
    }
   }
  }
  return {x : _round(x), y : _round(y)};
 },
 clone : function(bool) {
  if (this.length < 1) {
   return new KNode([]);
  }
  return new KNode(this[0].cloneNode(bool));
 },
 append : function(expr) {
  this.each(function() {
   if (this.appendChild) {
    this.appendChild(_get(expr));
   }
  });
  return this;
 },
 appendTo : function(expr) {
  this.each(function() {
   _get(expr).appendChild(this);
  });
  return this;
 },
 before : function(expr) {
  this.each(function() {
   this.parentNode.insertBefore(_get(expr), this);
  });
  return this;
 },
 after : function(expr) {
  this.each(function() {
   if (this.nextSibling) {
    this.parentNode.insertBefore(_get(expr), this.nextSibling);
   } else {
    this.parentNode.appendChild(_get(expr));
   }
  });
  return this;
 },
 replaceWith : function(expr) {
  var nodes = [];
  this.each(function(i, node) {
   _unbind(node);
   var newNode = _get(expr);
   node.parentNode.replaceChild(newNode, node);
   nodes.push(newNode);
  });
  return K(nodes);
 },
 empty : function() {
  var self = this;
  self.each(function(i, node) {
   var child = node.firstChild;
   while (child) {
    if (!node.parentNode) {
     return;
    }
    var next = child.nextSibling;
    child.parentNode.removeChild(child);
    child = next;
   }
  });
  return self;
 },
 remove : function(keepChilds) {
  var self = this;
  self.each(function(i, node) {
   if (!node.parentNode) {
    return;
   }
   _unbind(node);
   if (keepChilds) {
    var child = node.firstChild;
    while (child) {
     var next = child.nextSibling;
     node.parentNode.insertBefore(child, node);
     child = next;
    }
   }
   node.parentNode.removeChild(node);
   delete self[i];
  });
  self.length = 0;
  return self;
 },
 show : function(val) {
  var self = this;
  if (val === undefined) {
   val = self._originDisplay || '';
  }
  if (self.css('display') != 'none') {
   return self;
  }
  return self.css('display', val);
 },
 hide : function() {
  var self = this;
  if (self.length < 1) {
   return self;
  }
  self._originDisplay = self[0].style.display;
  return self.css('display', 'none');
 },
 outer : function() {
  var self = this;
  if (self.length < 1) {
   return '';
  }
  var div = self.doc.createElement('div'), html;
  div.appendChild(self[0].cloneNode(true));
  html = _formatHtml(div.innerHTML);
  div = null;
  return html;
 },
 isSingle : function() {
  return !!_SINGLE_TAG_MAP[this.name];
 },
 isInline : function() {
  return !!_INLINE_TAG_MAP[this.name];
 },
 isBlock : function() {
  return !!_BLOCK_TAG_MAP[this.name];
 },
 isStyle : function() {
  return !!_STYLE_TAG_MAP[this.name];
 },
 isControl : function() {
  return !!_CONTROL_TAG_MAP[this.name];
 },
 contains : function(otherNode) {
  if (this.length < 1) {
   return false;
  }
  return _contains(this[0], _get(otherNode));
 },
 parent : function() {
  if (this.length < 1) {
   return null;
  }
  var node = this[0].parentNode;
  return node ? new KNode(node) : null;
 },
 children : function() {
  if (this.length < 1) {
   return new KNode([]);
  }
  var list = [], child = this[0].firstChild;
  while (child) {
   if (child.nodeType != 3 || _trim(child.nodeValue) !== '') {
    list.push(child);
   }
   child = child.nextSibling;
  }
  return new KNode(list);
 },
 first : function() {
  var list = this.children();
  return list.length > 0 ? list.eq(0) : null;
 },
 last : function() {
  var list = this.children();
  return list.length > 0 ? list.eq(list.length - 1) : null;
 },
 index : function() {
  if (this.length < 1) {
   return -1;
  }
  var i = -1, sibling = this[0];
  while (sibling) {
   i++;
   sibling = sibling.previousSibling;
  }
  return i;
 },
 prev : function() {
  if (this.length < 1) {
   return null;
  }
  var node = this[0].previousSibling;
  return node ? new KNode(node) : null;
 },
 next : function() {
  if (this.length < 1) {
   return null;
  }
  var node = this[0].nextSibling;
  return node ? new KNode(node) : null;
 },
 scan : function(fn, order) {
  if (this.length < 1) {
   return;
  }
  order = (order === undefined) ? true : order;
  function walk(node) {
   var n = order ? node.firstChild : node.lastChild;
   while (n) {
    var next = order ? n.nextSibling : n.previousSibling;
    if (fn(n) === false) {
     return false;
    }
    if (walk(n) === false) {
     return false;
    }
    n = next;
   }
  }
  walk(this[0]);
  return this;
 }
});
_each(('blur,focus,focusin,focusout,load,resize,scroll,unload,click,dblclick,' +
 'mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,' +
 'change,select,submit,keydown,keypress,keyup,error,contextmenu').split(','), function(i, type) {
 KNode.prototype[type] = function(fn) {
  return fn ? this.bind(type, fn) : this.fire(type);
 };
});
var _K = K;
K = function(expr, root) {
 if (expr === undefined || expr === null) {
  return;
 }
 function newNode(node) {
  if (!node[0]) {
   node = [];
  }
  return new KNode(node);
 }
 if (typeof expr === 'string') {
  if (root) {
   root = _get(root);
  }
  var length = expr.length;
  if (expr.charAt(0) === '@') {
   expr = expr.substr(1);
  }
  if (expr.length !== length || /<.+>/.test(expr)) {
   var doc = root ? root.ownerDocument || root : document,
    div = doc.createElement('div'), list = [];
   div.innerHTML = '<img id="__kindeditor_temp_tag__" width="0" height="0" style="display:none;" />' + expr;
   for (var i = 0, len = div.childNodes.length; i < len; i++) {
    var child = div.childNodes[i];
    if (child.id == '__kindeditor_temp_tag__') {
     continue;
    }
    list.push(child);
   }
   return newNode(list);
  }
  return newNode(_queryAll(expr, root));
 }
 if (expr && expr.constructor === KNode) {
  return expr;
 }
 if (expr.toArray) {
  expr = expr.toArray();
 }
 if (_isArray(expr)) {
  return newNode(expr);
 }
 return newNode(_toArray(arguments));
};
_each(_K, function(key, val) {
 K[key] = val;
});
K.NodeClass = KNode;
window.KindEditor = K;
var _START_TO_START = 0,
 _START_TO_END = 1,
 _END_TO_END = 2,
 _END_TO_START = 3,
 _BOOKMARK_ID = 0;
function _updateCollapsed(range) {
 range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset);
 return range;
}
function _copyAndDelete(range, isCopy, isDelete) {
 var doc = range.doc, nodeList = [];
 function splitTextNode(node, startOffset, endOffset) {
  var length = node.nodeValue.length, centerNode;
  if (isCopy) {
   var cloneNode = node.cloneNode(true);
   if (startOffset > 0) {
    centerNode = cloneNode.splitText(startOffset);
   } else {
    centerNode = cloneNode;
   }
   if (endOffset < length) {
    centerNode.splitText(endOffset - startOffset);
   }
  }
  if (isDelete) {
   var center = node;
   if (startOffset > 0) {
    center = node.splitText(startOffset);
    range.setStart(node, startOffset);
   }
   if (endOffset < length) {
    var right = center.splitText(endOffset - startOffset);
    range.setEnd(right, 0);
   }
   nodeList.push(center);
  }
  return centerNode;
 }
 function removeNodes() {
  if (isDelete) {
   range.up().collapse(true);
  }
  for (var i = 0, len = nodeList.length; i < len; i++) {
   var node = nodeList[i];
   if (node.parentNode) {
    node.parentNode.removeChild(node);
   }
  }
 }
 var copyRange = range.cloneRange().down();
 var start = -1, incStart = -1, incEnd = -1, end = -1,
  ancestor = range.commonAncestor(), frag = doc.createDocumentFragment();
 if (ancestor.nodeType == 3) {
  var textNode = splitTextNode(ancestor, range.startOffset, range.endOffset);
  if (isCopy) {
   frag.appendChild(textNode);
  }
  removeNodes();
  return isCopy ? frag : range;
 }
 function extractNodes(parent, frag) {
  var node = parent.firstChild, nextNode;
  while (node) {
   var testRange = new KRange(doc).selectNode(node);
   start = testRange.compareBoundaryPoints(_START_TO_END, range);
   if (start >= 0 && incStart <= 0) {
    incStart = testRange.compareBoundaryPoints(_START_TO_START, range);
   }
   if (incStart >= 0 && incEnd <= 0) {
    incEnd = testRange.compareBoundaryPoints(_END_TO_END, range);
   }
   if (incEnd >= 0 && end <= 0) {
    end = testRange.compareBoundaryPoints(_END_TO_START, range);
   }
   if (end >= 0) {
    return false;
   }
   nextNode = node.nextSibling;
   if (start > 0) {
    if (node.nodeType == 1) {
     if (incStart >= 0 && incEnd <= 0) {
      if (isCopy) {
       frag.appendChild(node.cloneNode(true));
      }
      if (isDelete) {
       nodeList.push(node);
      }
     } else {
      var childFlag;
      if (isCopy) {
       childFlag = node.cloneNode(false);
       frag.appendChild(childFlag);
      }
      if (extractNodes(node, childFlag) === false) {
       return false;
      }
     }
    } else if (node.nodeType == 3) {
     var textNode;
     if (node == copyRange.startContainer) {
      textNode = splitTextNode(node, copyRange.startOffset, node.nodeValue.length);
     } else if (node == copyRange.endContainer) {
      textNode = splitTextNode(node, 0, copyRange.endOffset);
     } else {
      textNode = splitTextNode(node, 0, node.nodeValue.length);
     }
     if (isCopy) {
      try {
       frag.appendChild(textNode);
      } catch(e) {}
     }
    }
   }
   node = nextNode;
  }
 }
 extractNodes(ancestor, frag);
 if (isDelete) {
  range.up().collapse(true);
 }
 for (var i = 0, len = nodeList.length; i < len; i++) {
  var node = nodeList[i];
  if (node.parentNode) {
   node.parentNode.removeChild(node);
  }
 }
 return isCopy ? frag : range;
}
function _moveToElementText(range, el) {
 var node = el;
 while (node) {
  var knode = K(node);
  if (knode.name == 'marquee' || knode.name == 'select') {
   return;
  }
  node = node.parentNode;
 }
 try {
  range.moveToElementText(el);
 } catch(e) {}
}
function _getStartEnd(rng, isStart) {
 var doc = rng.parentElement().ownerDocument,
  pointRange = rng.duplicate();
 pointRange.collapse(isStart);
 var parent = pointRange.parentElement(),
  nodes = parent.childNodes;
 if (nodes.length === 0) {
  return {node: parent.parentNode, offset: K(parent).index()};
 }
 var startNode = doc, startPos = 0, cmp = -1;
 var testRange = rng.duplicate();
 _moveToElementText(testRange, parent);
 for (var i = 0, len = nodes.length; i < len; i++) {
  var node = nodes[i];
  cmp = testRange.compareEndPoints('StartToStart', pointRange);
  if (cmp === 0) {
   return {node: node.parentNode, offset: i};
  }
  if (node.nodeType == 1) {
   var nodeRange = rng.duplicate(), dummy, knode = K(node), newNode = node;
   if (knode.isControl()) {
    dummy = doc.createElement('span');
    knode.after(dummy);
    newNode = dummy;
    startPos += knode.text().replace(/\r\n|\n|\r/g, '').length;
   }
   _moveToElementText(nodeRange, newNode);
   testRange.setEndPoint('StartToEnd', nodeRange);
   if (cmp > 0) {
    startPos += nodeRange.text.replace(/\r\n|\n|\r/g, '').length;
   } else {
    startPos = 0;
   }
   if (dummy) {
    K(dummy).remove();
   }
  } else if (node.nodeType == 3) {
   testRange.moveStart('character', node.nodeValue.length);
   startPos += node.nodeValue.length;
  }
  if (cmp < 0) {
   startNode = node;
  }
 }
 if (cmp < 0 && startNode.nodeType == 1) {
  return {node: parent, offset: K(parent.lastChild).index() + 1};
 }
 if (cmp > 0) {
  while (startNode.nextSibling && startNode.nodeType == 1) {
   startNode = startNode.nextSibling;
  }
 }
 testRange = rng.duplicate();
 _moveToElementText(testRange, parent);
 testRange.setEndPoint('StartToEnd', pointRange);
 startPos -= testRange.text.replace(/\r\n|\n|\r/g, '').length;
 if (cmp > 0 && startNode.nodeType == 3) {
  var prevNode = startNode.previousSibling;
  while (prevNode && prevNode.nodeType == 3) {
   startPos -= prevNode.nodeValue.length;
   prevNode = prevNode.previousSibling;
  }
 }
 return {node: startNode, offset: startPos};
}
function _getEndRange(node, offset) {
 var doc = node.ownerDocument || node,
  range = doc.body.createTextRange();
 if (doc == node) {
  range.collapse(true);
  return range;
 }
 if (node.nodeType == 1 && node.childNodes.length > 0) {
  var children = node.childNodes, isStart, child;
  if (offset === 0) {
   child = children[0];
   isStart = true;
  } else {
   child = children[offset - 1];
   isStart = false;
  }
  if (!child) {
   return range;
  }
  if (K(child).name === 'head') {
   if (offset === 1) {
    isStart = true;
   }
   if (offset === 2) {
    isStart = false;
   }
   range.collapse(isStart);
   return range;
  }
  if (child.nodeType == 1) {
   var kchild = K(child), span;
   if (kchild.isControl()) {
    span = doc.createElement('span');
    if (isStart) {
     kchild.before(span);
    } else {
     kchild.after(span);
    }
    child = span;
   }
   _moveToElementText(range, child);
   range.collapse(isStart);
   if (span) {
    K(span).remove();
   }
   return range;
  }
  node = child;
  offset = isStart ? 0 : child.nodeValue.length;
 }
 var dummy = doc.createElement('span');
 K(node).before(dummy);
 _moveToElementText(range, dummy);
 range.moveStart('character', offset);
 K(dummy).remove();
 return range;
}
function _toRange(rng) {
 var doc, range;
 function tr2td(start) {
  if (K(start.node).name == 'tr') {
   start.node = start.node.cells[start.offset];
   start.offset = 0;
  }
 }
 if (_IE) {
  if (rng.item) {
   doc = _getDoc(rng.item(0));
   range = new KRange(doc);
   range.selectNode(rng.item(0));
   return range;
  }
  doc = rng.parentElement().ownerDocument;
  var start = _getStartEnd(rng, true),
   end = _getStartEnd(rng, false);
  tr2td(start);
  tr2td(end);
  range = new KRange(doc);
  range.setStart(start.node, start.offset);
  range.setEnd(end.node, end.offset);
  return range;
 }
 var startContainer = rng.startContainer;
 doc = startContainer.ownerDocument || startContainer;
 range = new KRange(doc);
 range.setStart(startContainer, rng.startOffset);
 range.setEnd(rng.endContainer, rng.endOffset);
 return range;
}
function KRange(doc) {
 this.init(doc);
}
_extend(KRange, {
 init : function(doc) {
  var self = this;
  self.startContainer = doc;
  self.startOffset = 0;
  self.endContainer = doc;
  self.endOffset = 0;
  self.collapsed = true;
  self.doc = doc;
 },
 commonAncestor : function() {
  function getParents(node) {
   var parents = [];
   while (node) {
    parents.push(node);
    node = node.parentNode;
   }
   return parents;
  }
  var parentsA = getParents(this.startContainer),
   parentsB = getParents(this.endContainer),
   i = 0, lenA = parentsA.length, lenB = parentsB.length, parentA, parentB;
  while (++i) {
   parentA = parentsA[lenA - i];
   parentB = parentsB[lenB - i];
   if (!parentA || !parentB || parentA !== parentB) {
    break;
   }
  }
  return parentsA[lenA - i + 1];
 },
 setStart : function(node, offset) {
  var self = this, doc = self.doc;
  self.startContainer = node;
  self.startOffset = offset;
  if (self.endContainer === doc) {
   self.endContainer = node;
   self.endOffset = offset;
  }
  return _updateCollapsed(this);
 },
 setEnd : function(node, offset) {
  var self = this, doc = self.doc;
  self.endContainer = node;
  self.endOffset = offset;
  if (self.startContainer === doc) {
   self.startContainer = node;
   self.startOffset = offset;
  }
  return _updateCollapsed(this);
 },
 setStartBefore : function(node) {
  return this.setStart(node.parentNode || this.doc, K(node).index());
 },
 setStartAfter : function(node) {
  return this.setStart(node.parentNode || this.doc, K(node).index() + 1);
 },
 setEndBefore : function(node) {
  return this.setEnd(node.parentNode || this.doc, K(node).index());
 },
 setEndAfter : function(node) {
  return this.setEnd(node.parentNode || this.doc, K(node).index() + 1);
 },
 selectNode : function(node) {
  return this.setStartBefore(node).setEndAfter(node);
 },
 selectNodeContents : function(node) {
  var knode = K(node);
  if (knode.type == 3 || knode.isSingle()) {
   return this.selectNode(node);
  }
  var children = knode.children();
  if (children.length > 0) {
   return this.setStartBefore(children[0]).setEndAfter(children[children.length - 1]);
  }
  return this.setStart(node, 0).setEnd(node, 0);
 },
 collapse : function(toStart) {
  if (toStart) {
   return this.setEnd(this.startContainer, this.startOffset);
  }
  return this.setStart(this.endContainer, this.endOffset);
 },
 compareBoundaryPoints : function(how, range) {
  var rangeA = this.get(), rangeB = range.get();
  if (_IE) {
   var arr = {};
   arr[_START_TO_START] = 'StartToStart';
   arr[_START_TO_END] = 'EndToStart';
   arr[_END_TO_END] = 'EndToEnd';
   arr[_END_TO_START] = 'StartToEnd';
   var cmp = rangeA.compareEndPoints(arr[how], rangeB);
   if (cmp !== 0) {
    return cmp;
   }
   var nodeA, nodeB, nodeC, posA, posB;
   if (how === _START_TO_START || how === _END_TO_START) {
    nodeA = this.startContainer;
    posA = this.startOffset;
   }
   if (how === _START_TO_END || how === _END_TO_END) {
    nodeA = this.endContainer;
    posA = this.endOffset;
   }
   if (how === _START_TO_START || how === _START_TO_END) {
    nodeB = range.startContainer;
    posB = range.startOffset;
   }
   if (how === _END_TO_END || how === _END_TO_START) {
    nodeB = range.endContainer;
    posB = range.endOffset;
   }
   if (nodeA === nodeB) {
    var diff = posA - posB;
    return diff > 0 ? 1 : (diff < 0 ? -1 : 0);
   }
   nodeC = nodeB;
   while (nodeC && nodeC.parentNode !== nodeA) {
    nodeC = nodeC.parentNode;
   }
   if (nodeC) {
    return K(nodeC).index() >= posA ? -1 : 1;
   }
   nodeC = nodeA;
   while (nodeC && nodeC.parentNode !== nodeB) {
    nodeC = nodeC.parentNode;
   }
   if (nodeC) {
    return K(nodeC).index() >= posB ? 1 : -1;
   }
   nodeC = K(nodeB).next();
   if (nodeC && nodeC.contains(nodeA)) {
    return 1;
   }
   nodeC = K(nodeA).next();
   if (nodeC && nodeC.contains(nodeB)) {
    return -1;
   }
  } else {
   return rangeA.compareBoundaryPoints(how, rangeB);
  }
 },
 cloneRange : function() {
  return new KRange(this.doc).setStart(this.startContainer, this.startOffset).setEnd(this.endContainer, this.endOffset);
 },
 toString : function() {
  var rng = this.get(), str = _IE ? rng.text : rng.toString();
  return str.replace(/\r\n|\n|\r/g, '');
 },
 cloneContents : function() {
  return _copyAndDelete(this, true, false);
 },
 deleteContents : function() {
  return _copyAndDelete(this, false, true);
 },
 extractContents : function() {
  return _copyAndDelete(this, true, true);
 },
 insertNode : function(node) {
  var self = this,
   sc = self.startContainer, so = self.startOffset,
   ec = self.endContainer, eo = self.endOffset,
   firstChild, lastChild, c, nodeCount = 1;
  if (node.nodeName.toLowerCase() === '#document-fragment') {
   firstChild = node.firstChild;
   lastChild = node.lastChild;
   nodeCount = node.childNodes.length;
  }
  if (sc.nodeType == 1) {
   c = sc.childNodes[so];
   if (c) {
    sc.insertBefore(node, c);
    if (sc === ec) {
     eo += nodeCount;
    }
   } else {
    sc.appendChild(node);
   }
  } else if (sc.nodeType == 3) {
   if (so === 0) {
    sc.parentNode.insertBefore(node, sc);
    if (sc.parentNode === ec) {
     eo += nodeCount;
    }
   } else if (so >= sc.nodeValue.length) {
    if (sc.nextSibling) {
     sc.parentNode.insertBefore(node, sc.nextSibling);
    } else {
     sc.parentNode.appendChild(node);
    }
   } else {
    if (so > 0) {
     c = sc.splitText(so);
    } else {
     c = sc;
    }
    sc.parentNode.insertBefore(node, c);
    if (sc === ec) {
     ec = c;
     eo -= so;
    }
   }
  }
  if (firstChild) {
   self.setStartBefore(firstChild).setEndAfter(lastChild);
  } else {
   self.selectNode(node);
  }
  if (self.compareBoundaryPoints(_END_TO_END, self.cloneRange().setEnd(ec, eo)) >= 1) {
   return self;
  }
  return self.setEnd(ec, eo);
 },
 surroundContents : function(node) {
  node.appendChild(this.extractContents());
  return this.insertNode(node).selectNode(node);
 },
 isControl : function() {
  var self = this,
   sc = self.startContainer, so = self.startOffset,
   ec = self.endContainer, eo = self.endOffset, rng;
  return sc.nodeType == 1 && sc === ec && so + 1 === eo && K(sc.childNodes[so]).isControl();
 },
 get : function(hasControlRange) {
  var self = this, doc = self.doc, node, rng;
  if (!_IE) {
   rng = doc.createRange();
   try {
    rng.setStart(self.startContainer, self.startOffset);
    rng.setEnd(self.endContainer, self.endOffset);
   } catch (e) {}
   return rng;
  }
  if (hasControlRange && self.isControl()) {
   rng = doc.body.createControlRange();
   rng.addElement(self.startContainer.childNodes[self.startOffset]);
   return rng;
  }
  var range = self.cloneRange().down();
  rng = doc.body.createTextRange();
  rng.setEndPoint('StartToStart', _getEndRange(range.startContainer, range.startOffset));
  rng.setEndPoint('EndToStart', _getEndRange(range.endContainer, range.endOffset));
  return rng;
 },
 html : function() {
  return K(this.cloneContents()).outer();
 },
 down : function() {
  var self = this;
  function downPos(node, pos, isStart) {
   if (node.nodeType != 1) {
    return;
   }
   var children = K(node).children();
   if (children.length === 0) {
    return;
   }
   var left, right, child, offset;
   if (pos > 0) {
    left = children.eq(pos - 1);
   }
   if (pos < children.length) {
    right = children.eq(pos);
   }
   if (left && left.type == 3) {
    child = left[0];
    offset = child.nodeValue.length;
   }
   if (right && right.type == 3) {
    child = right[0];
    offset = 0;
   }
   if (!child) {
    return;
   }
   if (isStart) {
    self.setStart(child, offset);
   } else {
    self.setEnd(child, offset);
   }
  }
  downPos(self.startContainer, self.startOffset, true);
  downPos(self.endContainer, self.endOffset, false);
  return self;
 },
 up : function() {
  var self = this;
  function upPos(node, pos, isStart) {
   if (node.nodeType != 3) {
    return;
   }
   if (pos === 0) {
    if (isStart) {
     self.setStartBefore(node);
    } else {
     self.setEndBefore(node);
    }
   } else if (pos == node.nodeValue.length) {
    if (isStart) {
     self.setStartAfter(node);
    } else {
     self.setEndAfter(node);
    }
   }
  }
  upPos(self.startContainer, self.startOffset, true);
  upPos(self.endContainer, self.endOffset, false);
  return self;
 },
 enlarge : function(toBlock) {
  var self = this;
  self.up();
  function enlargePos(node, pos, isStart) {
   var knode = K(node), parent;
   if (knode.type == 3 || _NOSPLIT_TAG_MAP[knode.name] || !toBlock && knode.isBlock()) {
    return;
   }
   if (pos === 0) {
    while (!knode.prev()) {
     parent = knode.parent();
     if (!parent || _NOSPLIT_TAG_MAP[parent.name] || !toBlock && parent.isBlock()) {
      break;
     }
     knode = parent;
    }
    if (isStart) {
     self.setStartBefore(knode[0]);
    } else {
     self.setEndBefore(knode[0]);
    }
   } else if (pos == knode.children().length) {
    while (!knode.next()) {
     parent = knode.parent();
     if (!parent || _NOSPLIT_TAG_MAP[parent.name] || !toBlock && parent.isBlock()) {
      break;
     }
     knode = parent;
    }
    if (isStart) {
     self.setStartAfter(knode[0]);
    } else {
     self.setEndAfter(knode[0]);
    }
   }
  }
  enlargePos(self.startContainer, self.startOffset, true);
  enlargePos(self.endContainer, self.endOffset, false);
  return self;
 },
 shrink : function() {
  var self = this, child, collapsed = self.collapsed;
  while (self.startContainer.nodeType == 1 && (child = self.startContainer.childNodes[self.startOffset]) && child.nodeType == 1 && !K(child).isSingle()) {
   self.setStart(child, 0);
  }
  if (collapsed) {
   return self.collapse(collapsed);
  }
  while (self.endContainer.nodeType == 1 && self.endOffset > 0 && (child = self.endContainer.childNodes[self.endOffset - 1]) && child.nodeType == 1 && !K(child).isSingle()) {
   self.setEnd(child, child.childNodes.length);
  }
  return self;
 },
 createBookmark : function(serialize) {
  var self = this, doc = self.doc, endNode,
   startNode = K('<span style="display:none;"></span>', doc)[0];
  startNode.id = '__kindeditor_bookmark_start_' + (_BOOKMARK_ID++) + '__';
  if (!self.collapsed) {
   endNode = startNode.cloneNode(true);
   endNode.id = '__kindeditor_bookmark_end_' + (_BOOKMARK_ID++) + '__';
  }
  if (endNode) {
   self.cloneRange().collapse(false).insertNode(endNode).setEndBefore(endNode);
  }
  self.insertNode(startNode).setStartAfter(startNode);
  return {
   start : serialize ? '#' + startNode.id : startNode,
   end : endNode ? (serialize ? '#' + endNode.id : endNode) : null
  };
 },
 moveToBookmark : function(bookmark) {
  var self = this, doc = self.doc,
   start = K(bookmark.start, doc), end = bookmark.end ? K(bookmark.end, doc) : null;
  if (!start || start.length < 1) {
   return self;
  }
  self.setStartBefore(start[0]);
  start.remove();
  if (end && end.length > 0) {
   self.setEndBefore(end[0]);
   end.remove();
  } else {
   self.collapse(true);
  }
  return self;
 },
 dump : function() {
  console.log('--------------------');
  console.log(this.startContainer.nodeType == 3 ? this.startContainer.nodeValue : this.startContainer, this.startOffset);
  console.log(this.endContainer.nodeType == 3 ? this.endContainer.nodeValue : this.endContainer, this.endOffset);
 }
});
function _range(mixed) {
 if (!mixed.nodeName) {
  return mixed.constructor === KRange ? mixed : _toRange(mixed);
 }
 return new KRange(mixed);
}
K.RangeClass = KRange;
K.range = _range;
K.START_TO_START = _START_TO_START;
K.START_TO_END = _START_TO_END;
K.END_TO_END = _END_TO_END;
K.END_TO_START = _END_TO_START;
function _nativeCommand(doc, key, val) {
 try {
  doc.execCommand(key, false, val);
 } catch(e) {}
}
function _nativeCommandValue(doc, key) {
 var val = '';
 try {
  val = doc.queryCommandValue(key);
 } catch (e) {}
 if (typeof val !== 'string') {
  val = '';
 }
 return val;
}
function _getSel(doc) {
 var win = _getWin(doc);
 return doc.selection || win.getSelection();
}
function _getRng(doc) {
 var sel = _getSel(doc), rng;
 try {
  if (sel.rangeCount > 0) {
   rng = sel.getRangeAt(0);
  } else {
   rng = sel.createRange();
  }
 } catch(e) {}
 if (_IE && (!rng || (!rng.item && rng.parentElement().ownerDocument !== doc))) {
  return null;
 }
 return rng;
}
function _singleKeyMap(map) {
 var newMap = {}, arr, v;
 _each(map, function(key, val) {
  arr = key.split(',');
  for (var i = 0, len = arr.length; i < len; i++) {
   v = arr[i];
   newMap[v] = val;
  }
 });
 return newMap;
}
function _hasAttrOrCss(knode, map) {
 return _hasAttrOrCssByKey(knode, map, '*') || _hasAttrOrCssByKey(knode, map);
}
function _hasAttrOrCssByKey(knode, map, mapKey) {
 mapKey = mapKey || knode.name;
 if (knode.type !== 1) {
  return false;
 }
 var newMap = _singleKeyMap(map);
 if (!newMap[mapKey]) {
  return false;
 }
 var arr = newMap[mapKey].split(',');
 for (var i = 0, len = arr.length; i < len; i++) {
  var key = arr[i];
  if (key === '*') {
   return true;
  }
  var match = /^(\.?)([^=]+)(?:=([^=]*))?$/.exec(key);
  var method = match[1] ? 'css' : 'attr';
  key = match[2];
  var val = match[3] || '';
  if (val === '' && knode[method](key) !== '') {
   return true;
  }
  if (val !== '' && knode[method](key) === val) {
   return true;
  }
 }
 return false;
}
function _removeAttrOrCss(knode, map) {
 if (knode.type != 1) {
  return;
 }
 _removeAttrOrCssByKey(knode, map, '*');
 _removeAttrOrCssByKey(knode, map);
}
function _removeAttrOrCssByKey(knode, map, mapKey) {
 mapKey = mapKey || knode.name;
 if (knode.type !== 1) {
  return;
 }
 var newMap = _singleKeyMap(map);
 if (!newMap[mapKey]) {
  return;
 }
 var arr = newMap[mapKey].split(','), allFlag = false;
 for (var i = 0, len = arr.length; i < len; i++) {
  var key = arr[i];
  if (key === '*') {
   allFlag = true;
   break;
  }
  var match = /^(\.?)([^=]+)(?:=([^=]*))?$/.exec(key);
  key = match[2];
  if (match[1]) {
   key = _toCamel(key);
   if (knode[0].style[key]) {
    knode[0].style[key] = '';
   }
  } else {
   knode.removeAttr(key);
  }
 }
 if (allFlag) {
  knode.remove(true);
 }
}
function _getInnerNode(knode) {
 var inner = knode;
 while (inner.first()) {
  inner = inner.first();
 }
 return inner;
}
function _isEmptyNode(knode) {
 return knode.type == 1 && knode.html().replace(/<[^>]+>/g, '') === '';
}
function _mergeWrapper(a, b) {
 a = a.clone(true);
 var lastA = _getInnerNode(a), childA = a, merged = false;
 while (b) {
  while (childA) {
   if (childA.name === b.name) {
    _mergeAttrs(childA, b.attr(), b.css());
    merged = true;
   }
   childA = childA.first();
  }
  if (!merged) {
   lastA.append(b.clone(false));
  }
  merged = false;
  b = b.first();
 }
 return a;
}
function _wrapNode(knode, wrapper) {
 wrapper = wrapper.clone(true);
 if (knode.type == 3) {
  _getInnerNode(wrapper).append(knode.clone(false));
  knode.replaceWith(wrapper);
  return wrapper;
 }
 var nodeWrapper = knode, child;
 while ((child = knode.first()) && child.children().length == 1) {
  knode = child;
 }
 child = knode.first();
 var frag = knode.doc.createDocumentFragment();
 while (child) {
  frag.appendChild(child[0]);
  child = child.next();
 }
 wrapper = _mergeWrapper(nodeWrapper, wrapper);
 if (frag.firstChild) {
  _getInnerNode(wrapper).append(frag);
 }
 nodeWrapper.replaceWith(wrapper);
 return wrapper;
}
function _mergeAttrs(knode, attrs, styles) {
 _each(attrs, function(key, val) {
  if (key !== 'style') {
   knode.attr(key, val);
  }
 });
 _each(styles, function(key, val) {
  knode.css(key, val);
 });
}
function _inPreElement(knode) {
 while (knode && knode.name != 'body') {
  if (_PRE_TAG_MAP[knode.name] || knode.name == 'div' && knode.hasClass('ke-script')) {
   return true;
  }
  knode = knode.parent();
 }
 return false;
}
function KCmd(range) {
 this.init(range);
}
_extend(KCmd, {
 init : function(range) {
  var self = this, doc = range.doc;
  self.doc = doc;
  self.win = _getWin(doc);
  self.sel = _getSel(doc);
  self.range = range;
 },
 selection : function(forceReset) {
  var self = this, doc = self.doc, rng = _getRng(doc);
  self.sel = _getSel(doc);
  if (rng) {
   self.range = _range(rng);
   if (K(self.range.startContainer).name == 'html') {
    self.range.selectNodeContents(doc.body).collapse(false);
   }
   return self;
  }
  if (forceReset) {
   self.range.selectNodeContents(doc.body).collapse(false);
  }
  return self;
 },
 select : function(hasDummy) {
  hasDummy = _undef(hasDummy, true);
  var self = this, sel = self.sel, range = self.range.cloneRange().shrink(),
   sc = range.startContainer, so = range.startOffset,
   ec = range.endContainer, eo = range.endOffset,
   doc = _getDoc(sc), win = self.win, rng, hasU200b = false;
  if (hasDummy && sc.nodeType == 1 && range.collapsed) {
   if (_IE) {
    var dummy = K('<span>&nbsp;</span>', doc);
    range.insertNode(dummy[0]);
    rng = doc.body.createTextRange();
    try {
     rng.moveToElementText(dummy[0]);
    } catch(ex) {}
    rng.collapse(false);
    rng.select();
    dummy.remove();
    win.focus();
    return self;
   }
   if (_WEBKIT) {
    var children = sc.childNodes;
    if (K(sc).isInline() || so > 0 && K(children[so - 1]).isInline() || children[so] && K(children[so]).isInline()) {
     range.insertNode(doc.createTextNode('\u200B'));
     hasU200b = true;
    }
   }
  }
  if (_IE) {
   try {
    rng = range.get(true);
    rng.select();
   } catch(e) {}
  } else {
   if (hasU200b) {
    range.collapse(false);
   }
   rng = range.get(true);
   sel.removeAllRanges();
   sel.addRange(rng);
   var pos = K(rng.endContainer).pos();
   win.scrollTo(pos.x, pos.y);
  }
  win.focus();
  return self;
 },
 wrap : function(val) {
  var self = this, doc = self.doc, range = self.range, wrapper;
  wrapper = K(val, doc);
  if (range.collapsed) {
   range.shrink();
   range.insertNode(wrapper[0]).selectNodeContents(wrapper[0]);
   return self;
  }
  if (wrapper.isBlock()) {
   var copyWrapper = wrapper.clone(true), child = copyWrapper;
   while (child.first()) {
    child = child.first();
   }
   child.append(range.extractContents());
   range.insertNode(copyWrapper[0]).selectNode(copyWrapper[0]);
   return self;
  }
  range.enlarge();
  var bookmark = range.createBookmark(), ancestor = range.commonAncestor(), isStart = false;
  K(ancestor).scan(function(node) {
   if (!isStart && node == bookmark.start) {
    isStart = true;
    return;
   }
   if (isStart) {
    if (node == bookmark.end) {
     return false;
    }
    var knode = K(node);
    if (_inPreElement(knode)) {
     return;
    }
    if (knode.type == 3 && _trim(node.nodeValue).length > 0) {
     var parent;
     while ((parent = knode.parent()) && parent.isStyle() && parent.children().length == 1) {
      knode = parent;
     }
     _wrapNode(knode, wrapper);
    }
   }
  });
  range.moveToBookmark(bookmark);
  return self;
 },
 split : function(isStart, map) {
  var range = this.range, doc = range.doc;
  var tempRange = range.cloneRange().collapse(isStart);
  var node = tempRange.startContainer, pos = tempRange.startOffset,
   parent = node.nodeType == 3 ? node.parentNode : node,
   needSplit = false, knode;
  while (parent && parent.parentNode) {
   knode = K(parent);
   if (map) {
    if (!knode.isStyle()) {
     break;
    }
    if (!_hasAttrOrCss(knode, map)) {
     break;
    }
   } else {
    if (_NOSPLIT_TAG_MAP[knode.name]) {
     break;
    }
   }
   needSplit = true;
   parent = parent.parentNode;
  }
  if (needSplit) {
   var dummy = doc.createElement('span');
   range.cloneRange().collapse(!isStart).insertNode(dummy);
   if (isStart) {
    tempRange.setStartBefore(parent.firstChild).setEnd(node, pos);
   } else {
    tempRange.setStart(node, pos).setEndAfter(parent.lastChild);
   }
   var frag = tempRange.extractContents(),
    first = frag.firstChild, last = frag.lastChild;
   if (isStart) {
    tempRange.insertNode(frag);
    range.setStartAfter(last).setEndBefore(dummy);
   } else {
    parent.appendChild(frag);
    range.setStartBefore(dummy).setEndBefore(first);
   }
   var dummyParent = dummy.parentNode;
   if (dummyParent == range.endContainer) {
    var prev = K(dummy).prev(), next = K(dummy).next();
    if (prev && next && prev.type == 3 && next.type == 3) {
     range.setEnd(prev[0], prev[0].nodeValue.length);
    } else if (!isStart) {
     range.setEnd(range.endContainer, range.endOffset - 1);
    }
   }
   dummyParent.removeChild(dummy);
  }
  return this;
 },
 remove : function(map) {
  var self = this, doc = self.doc, range = self.range;
  range.enlarge();
  if (range.startOffset === 0) {
   var ksc = K(range.startContainer), parent;
   while ((parent = ksc.parent()) && parent.isStyle() && parent.children().length == 1) {
    ksc = parent;
   }
   range.setStart(ksc[0], 0);
   ksc = K(range.startContainer);
   if (ksc.isBlock()) {
    _removeAttrOrCss(ksc, map);
   }
   var kscp = ksc.parent();
   if (kscp && kscp.isBlock()) {
    _removeAttrOrCss(kscp, map);
   }
  }
  var sc, so;
  if (range.collapsed) {
   self.split(true, map);
   sc = range.startContainer;
   so = range.startOffset;
   if (so > 0) {
    var sb = K(sc.childNodes[so - 1]);
    if (sb && _isEmptyNode(sb)) {
     sb.remove();
     range.setStart(sc, so - 1);
    }
   }
   var sa = K(sc.childNodes[so]);
   if (sa && _isEmptyNode(sa)) {
    sa.remove();
   }
   if (_isEmptyNode(sc)) {
    range.startBefore(sc);
    sc.remove();
   }
   range.collapse(true);
   return self;
  }
  self.split(true, map);
  self.split(false, map);
  var startDummy = doc.createElement('span'), endDummy = doc.createElement('span');
  range.cloneRange().collapse(false).insertNode(endDummy);
  range.cloneRange().collapse(true).insertNode(startDummy);
  var nodeList = [], cmpStart = false;
  K(range.commonAncestor()).scan(function(node) {
   if (!cmpStart && node == startDummy) {
    cmpStart = true;
    return;
   }
   if (node == endDummy) {
    return false;
   }
   if (cmpStart) {
    nodeList.push(node);
   }
  });
  K(startDummy).remove();
  K(endDummy).remove();
  sc = range.startContainer;
  so = range.startOffset;
  var ec = range.endContainer, eo = range.endOffset;
  if (so > 0) {
   var startBefore = K(sc.childNodes[so - 1]);
   if (startBefore && _isEmptyNode(startBefore)) {
    startBefore.remove();
    range.setStart(sc, so - 1);
    if (sc == ec) {
     range.setEnd(ec, eo - 1);
    }
   }
   var startAfter = K(sc.childNodes[so]);
   if (startAfter && _isEmptyNode(startAfter)) {
    startAfter.remove();
    if (sc == ec) {
     range.setEnd(ec, eo - 1);
    }
   }
  }
  var endAfter = K(ec.childNodes[range.endOffset]);
  if (endAfter && _isEmptyNode(endAfter)) {
   endAfter.remove();
  }
  var bookmark = range.createBookmark(true);
  _each(nodeList, function(i, node) {
   _removeAttrOrCss(K(node), map);
  });
  range.moveToBookmark(bookmark);
  return self;
 },
 commonNode : function(map) {
  var range = this.range;
  var ec = range.endContainer, eo = range.endOffset,
   node = (ec.nodeType == 3 || eo === 0) ? ec : ec.childNodes[eo - 1];
  function find(node) {
   var child = node, parent = node;
   while (parent) {
    if (_hasAttrOrCss(K(parent), map)) {
     return K(parent);
    }
    parent = parent.parentNode;
   }
   while (child && (child = child.lastChild)) {
    if (_hasAttrOrCss(K(child), map)) {
     return K(child);
    }
   }
   return null;
  }
  var cNode = find(node);
  if (cNode) {
   return cNode;
  }
  if (node.nodeType == 1 || (ec.nodeType == 3 && eo === 0)) {
   var prev = K(node).prev();
   if (prev) {
    return find(prev);
   }
  }
  return null;
 },
 commonAncestor : function(tagName) {
  var range = this.range,
   sc = range.startContainer, so = range.startOffset,
   ec = range.endContainer, eo = range.endOffset,
   startNode = (sc.nodeType == 3 || so === 0) ? sc : sc.childNodes[so - 1],
   endNode = (ec.nodeType == 3 || eo === 0) ? ec : ec.childNodes[eo - 1];
  function find(node) {
   while (node) {
    if (node.nodeType == 1) {
     if (node.tagName.toLowerCase() === tagName) {
      return node;
     }
    }
    node = node.parentNode;
   }
   return null;
  }
  var start = find(startNode), end = find(endNode);
  if (start && end && start === end) {
   return K(start);
  }
  return null;
 },
 state : function(key) {
  var self = this, doc = self.doc, bool = false;
  try {
   bool = doc.queryCommandState(key);
  } catch (e) {}
  return bool;
 },
 val : function(key) {
  var self = this, doc = self.doc, range = self.range;
  function lc(val) {
   return val.toLowerCase();
  }
  key = lc(key);
  var val = '', knode;
  if (key === 'fontfamily' || key === 'fontname') {
   val = _nativeCommandValue(doc, 'fontname');
   val = val.replace(/['"]/g, '');
   return lc(val);
  }
  if (key === 'formatblock') {
   val = _nativeCommandValue(doc, key);
   if (val === '') {
    knode = self.commonNode({'h1,h2,h3,h4,h5,h6,p,div,pre,address' : '*'});
    if (knode) {
     val = knode.name;
    }
   }
   if (val === 'Normal') {
    val = 'p';
   }
   return lc(val);
  }
  if (key === 'fontsize') {
   knode = self.commonNode({'*' : '.font-size'});
   if (knode) {
    val = knode.css('font-size');
   }
   return lc(val);
  }
  if (key === 'forecolor') {
   knode = self.commonNode({'*' : '.color'});
   if (knode) {
    val = knode.css('color');
   }
   val = _toHex(val);
   if (val === '') {
    val = 'default';
   }
   return lc(val);
  }
  if (key === 'hilitecolor') {
   knode = self.commonNode({'*' : '.background-color'});
   if (knode) {
    val = knode.css('background-color');
   }
   val = _toHex(val);
   if (val === '') {
    val = 'default';
   }
   return lc(val);
  }
  return val;
 },
 toggle : function(wrapper, map) {
  var self = this;
  if (self.commonNode(map)) {
   self.remove(map);
  } else {
   self.wrap(wrapper);
  }
  return self.select();
 },
 bold : function() {
  return this.toggle('<strong></strong>', {
   span : '.font-weight=bold',
   strong : '*',
   b : '*'
  });
 },
 italic : function() {
  return this.toggle('<em></em>', {
   span : '.font-style=italic',
   em : '*',
   i : '*'
  });
 },
 underline : function() {
  return this.toggle('<u></u>', {
   span : '.text-decoration=underline',
   u : '*'
  });
 },
 strikethrough : function() {
  return this.toggle('<s></s>', {
   span : '.text-decoration=line-through',
   s : '*'
  });
 },
 forecolor : function(val) {
  return this.toggle('<span style="color:' + val + ';"></span>', {
   span : '.color=' + val,
   font : 'color'
  });
 },
 hilitecolor : function(val) {
  return this.toggle('<span style="background-color:' + val + ';"></span>', {
   span : '.background-color=' + val
  });
 },
 fontsize : function(val) {
  return this.toggle('<span style="font-size:' + val + ';"></span>', {
   span : '.font-size=' + val,
   font : 'size'
  });
 },
 fontname : function(val) {
  return this.fontfamily(val);
 },
 fontfamily : function(val) {
  return this.toggle('<span style="font-family:' + val + ';"></span>', {
   span : '.font-family=' + val,
   font : 'face'
  });
 },
 removeformat : function() {
  var map = {
   '*' : '.font-weight,.font-style,.text-decoration,.color,.background-color,.font-size,.font-family,.text-indent'
  },
  tags = _STYLE_TAG_MAP;
  _each(tags, function(key, val) {
   map[key] = '*';
  });
  this.remove(map);
  return this.select();
 },
 inserthtml : function(val, quickMode) {
  var self = this, range = self.range;
  if (val === '') {
   return self;
  }
  function pasteHtml(range, val) {
   val = '<img id="__kindeditor_temp_tag__" width="0" height="0" style="display:none;" />' + val;
   var rng = range.get();
   if (rng.item) {
    rng.item(0).outerHTML = val;
   } else {
    rng.pasteHTML(val);
   }
   var temp = range.doc.getElementById('__kindeditor_temp_tag__');
   temp.parentNode.removeChild(temp);
   var newRange = _toRange(rng);
   range.setEnd(newRange.endContainer, newRange.endOffset);
   range.collapse(false);
   self.select(false);
  }
  function insertHtml(range, val) {
   var doc = range.doc,
    frag = doc.createDocumentFragment();
   K('@' + val, doc).each(function() {
    frag.appendChild(this);
   });
   range.deleteContents();
   range.insertNode(frag);
   range.collapse(false);
   self.select(false);
  }
  if (_IE && quickMode) {
   try {
    pasteHtml(range, val);
   } catch(e) {
    insertHtml(range, val);
   }
   return self;
  }
  insertHtml(range, val);
  return self;
 },
 hr : function() {
  return this.inserthtml('<hr />');
 },
 print : function() {
  this.win.print();
  return this;
 },
 insertimage : function(url, title, width, height, border, align) {
  title = _undef(title, '');
  border = _undef(border, 0);
  var html = '<img src="' + _escape(url) + '" data-ke-src="' + _escape(url) + '" ';
  if (width) {
   html += 'width="' + _escape(width) + '" ';
  }
  if (height) {
   html += 'height="' + _escape(height) + '" ';
  }
  if (title) {
   html += 'title="' + _escape(title) + '" ';
  }
  if (align) {
   html += 'align="' + _escape(align) + '" ';
  }
  html += 'alt="' + _escape(title) + '" ';
  html += '/>';
  return this.inserthtml(html);
 },
 createlink : function(url, type) {
  var self = this, doc = self.doc, range = self.range;
  self.select();
  var a = self.commonNode({ a : '*' });
  if (a && !range.isControl()) {
   range.selectNode(a.get());
   self.select();
  }
  var html = '<a href="' + _escape(url) + '" data-ke-src="' + _escape(url) + '" ';
  if (type) {
   html += ' target="' + _escape(type) + '"';
  }
  if (range.collapsed) {
   html += '>' + _escape(url) + '</a>';
   return self.inserthtml(html);
  }
  if (range.isControl()) {
   var node = K(range.startContainer.childNodes[range.startOffset]);
   html += '></a>';
   node.after(K(html, doc));
   node.next().append(node);
   range.selectNode(node[0]);
   return self.select();
  }
  _nativeCommand(doc, 'createlink', '__kindeditor_temp_url__');
  K('a[href="__kindeditor_temp_url__"]', doc).each(function() {
   K(this).attr('href', url).attr('data-ke-src', url);
   if (type) {
    K(this).attr('target', type);
   } else {
    K(this).removeAttr('target');
   }
  });
  return self;
 },
 unlink : function() {
  var self = this, doc = self.doc, range = self.range;
  self.select();
  if (range.collapsed) {
   var a = self.commonNode({ a : '*' });
   if (a) {
    range.selectNode(a.get());
    self.select();
   }
   _nativeCommand(doc, 'unlink', null);
   if (_WEBKIT && K(range.startContainer).name === 'img') {
    var parent = K(range.startContainer).parent();
    if (parent.name === 'a') {
     parent.remove(true);
    }
   }
  } else {
   _nativeCommand(doc, 'unlink', null);
  }
  return self;
 }
});
_each(('formatblock,selectall,justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,' +
 'insertunorderedlist,indent,outdent,subscript,superscript').split(','), function(i, name) {
 KCmd.prototype[name] = function(val) {
  var self = this;
  self.select();
  _nativeCommand(self.doc, name, val);
  if (!_IE || _inArray(name, 'formatblock,selectall,insertorderedlist,insertunorderedlist'.split(',')) >= 0) {
   self.selection();
  }
  return self;
 };
});
_each('cut,copy,paste'.split(','), function(i, name) {
 KCmd.prototype[name] = function() {
  var self = this;
  if (!self.doc.queryCommandSupported(name)) {
   throw 'not supported';
  }
  self.select();
  _nativeCommand(self.doc, name, null);
  return self;
 };
});
function _cmd(mixed) {
 if (mixed.nodeName) {
  var doc = _getDoc(mixed);
  mixed = _range(doc).selectNodeContents(doc.body).collapse(false);
 }
 return new KCmd(mixed);
}
K.CmdClass = KCmd;
K.cmd = _cmd;
function _drag(options) {
 var moveEl = options.moveEl,
  moveFn = options.moveFn,
  clickEl = options.clickEl || moveEl,
  beforeDrag = options.beforeDrag,
  iframeFix = options.iframeFix === undefined ? true : options.iframeFix;
 var docs = [document];
 if (iframeFix) {
  K('iframe').each(function() {
   var src = _formatUrl(this.src || '', 'absolute');
   if (/^https?:\/\//.test(src)) {
    return;
   }
   var doc;
   try {
    doc = _iframeDoc(this);
   } catch(e) {}
   if (doc) {
    var pos = K(this).pos();
    K(doc).data('pos-x', pos.x);
    K(doc).data('pos-y', pos.y);
    docs.push(doc);
   }
  });
 }
 clickEl.mousedown(function(e) {
  e.stopPropagation();
  var self = clickEl.get(),
   x = _removeUnit(moveEl.css('left')),
   y = _removeUnit(moveEl.css('top')),
   width = moveEl.width(),
   height = moveEl.height(),
   pageX = e.pageX,
   pageY = e.pageY;
  if (beforeDrag) {
   beforeDrag();
  }
  function moveListener(e) {
   e.preventDefault();
   var kdoc = K(_getDoc(e.target));
   var diffX = _round((kdoc.data('pos-x') || 0) + e.pageX - pageX);
   var diffY = _round((kdoc.data('pos-y') || 0) + e.pageY - pageY);
   moveFn.call(clickEl, x, y, width, height, diffX, diffY);
  }
  function selectListener(e) {
   e.preventDefault();
  }
  function upListener(e) {
   e.preventDefault();
   K(docs).unbind('mousemove', moveListener)
    .unbind('mouseup', upListener)
    .unbind('selectstart', selectListener);
   if (self.releaseCapture) {
    self.releaseCapture();
   }
  }
  K(docs).mousemove(moveListener)
   .mouseup(upListener)
   .bind('selectstart', selectListener);
  if (self.setCapture) {
   self.setCapture();
  }
 });
}
function KWidget(options) {
 this.init(options);
}
_extend(KWidget, {
 init : function(options) {
  var self = this;
  self.name = options.name || '';
  self.doc = options.doc || document;
  self.win = _getWin(self.doc);
  self.x = _addUnit(options.x);
  self.y = _addUnit(options.y);
  self.z = options.z;
  self.width = _addUnit(options.width);
  self.height = _addUnit(options.height);
  self.div = K('<div style="display:block;"></div>');
  self.options = options;
  self._alignEl = options.alignEl;
  if (self.width) {
   self.div.css('width', self.width);
  }
  if (self.height) {
   self.div.css('height', self.height);
  }
  if (self.z) {
   self.div.css({
    position : 'absolute',
    left : self.x,
    top : self.y,
    'z-index' : self.z
   });
  }
  if (self.z && (self.x === undefined || self.y === undefined)) {
   self.autoPos(self.width, self.height);
  }
  if (options.cls) {
   self.div.addClass(options.cls);
  }
  if (options.shadowMode) {
   self.div.addClass('ke-shadow');
  }
  if (options.css) {
   self.div.css(options.css);
  }
  if (options.src) {
   K(options.src).replaceWith(self.div);
  } else {
   K(self.doc.body).append(self.div);
  }
  if (options.html) {
   self.div.html(options.html);
  }
  if (options.autoScroll) {
   if (_IE && _V < 7 || _QUIRKS) {
    var scrollPos = _getScrollPos();
    K(self.win).bind('scroll', function(e) {
     var pos = _getScrollPos(),
      diffX = pos.x - scrollPos.x,
      diffY = pos.y - scrollPos.y;
     self.pos(_removeUnit(self.x) + diffX, _removeUnit(self.y) + diffY, false);
    });
   } else {
    self.div.css('position', 'fixed');
   }
  }
 },
 pos : function(x, y, updateProp) {
  var self = this;
  updateProp = _undef(updateProp, true);
  if (x !== null) {
   x = x < 0 ? 0 : _addUnit(x);
   self.div.css('left', x);
   if (updateProp) {
    self.x = x;
   }
  }
  if (y !== null) {
   y = y < 0 ? 0 : _addUnit(y);
   self.div.css('top', y);
   if (updateProp) {
    self.y = y;
   }
  }
  return self;
 },
 autoPos : function(width, height) {
  var self = this,
   w = _removeUnit(width) || 0,
   h = _removeUnit(height) || 0,
   scrollPos = _getScrollPos();
  if (self._alignEl) {
   var knode = K(self._alignEl),
    pos = knode.pos(),
    diffX = _round(knode[0].clientWidth / 2 - w / 2),
    diffY = _round(knode[0].clientHeight / 2 - h / 2);
   x = diffX < 0 ? pos.x : pos.x + diffX;
   y = diffY < 0 ? pos.y : pos.y + diffY;
  } else {
   var docEl = _docElement(self.doc);
   x = _round(scrollPos.x + (docEl.clientWidth - w) / 2);
   y = _round(scrollPos.y + (docEl.clientHeight - h) / 2);
  }
  if (!(_IE && _V < 7 || _QUIRKS)) {
   x -= scrollPos.x;
   y -= scrollPos.y;
  }
  return self.pos(x, y);
 },
 remove : function() {
  var self = this;
  if (_IE && _V < 7 || _QUIRKS) {
   K(self.win).unbind('scroll');
  }
  self.div.remove();
  _each(self, function(i) {
   self[i] = null;
  });
  return this;
 },
 show : function() {
  this.div.show();
  return this;
 },
 hide : function() {
  this.div.hide();
  return this;
 },
 draggable : function(options) {
  var self = this;
  options = options || {};
  options.moveEl = self.div;
  options.moveFn = function(x, y, width, height, diffX, diffY) {
   if ((x = x + diffX) < 0) {
    x = 0;
   }
   if ((y = y + diffY) < 0) {
    y = 0;
   }
   self.pos(x, y);
  };
  _drag(options);
  return self;
 }
});
function _widget(options) {
 return new KWidget(options);
}
K.WidgetClass = KWidget;
K.widget = _widget;
function _iframeDoc(iframe) {
 iframe = _get(iframe);
 return iframe.contentDocument || iframe.contentWindow.document;
}
var html, _direction = '';
if ((html = document.getElementsByTagName('html'))) {
 _direction = html[0].dir;
}
function _getInitHtml(themesPath, bodyClass, cssPath, cssData) {
 var arr = [
  (_direction === '' ? '<html>' : '<html dir="' + _direction + '">'),
  '<head><meta charset="utf-8" /><title></title>',
  '<style>',
  'html {margin:0;padding:0;}',
  'body {margin:0;padding:5px;}',
  'body, td {font:12px/1.5 "sans serif",tahoma,verdana,helvetica;}',
  'body, p, div {word-wrap: break-word;}',
  'p {margin:5px 0;}',
  'table {border-collapse:collapse;}',
  'img {border:0;}',
  'noscript {display:none;}',
  'table.ke-zeroborder td {border:1px dotted #AAA;}',
  'img.ke-flash {',
  ' border:1px solid #AAA;',
  ' background-image:url(' + themesPath + 'common/flash.gif);',
  ' background-position:center center;',
  ' background-repeat:no-repeat;',
  ' width:100px;',
  ' height:100px;',
  '}',
  'img.ke-rm {',
  ' border:1px solid #AAA;',
  ' background-image:url(' + themesPath + 'common/rm.gif);',
  ' background-position:center center;',
  ' background-repeat:no-repeat;',
  ' width:100px;',
  ' height:100px;',
  '}',
  'img.ke-media {',
  ' border:1px solid #AAA;',
  ' background-image:url(' + themesPath + 'common/media.gif);',
  ' background-position:center center;',
  ' background-repeat:no-repeat;',
  ' width:100px;',
  ' height:100px;',
  '}',
  'img.ke-anchor {',
  ' border:1px dashed #666;',
  ' width:16px;',
  ' height:16px;',
  '}',
  '.ke-script, .ke-noscript, .ke-display-none {',
  ' display:none;',
  ' font-size:0;',
  ' width:0;',
  ' height:0;',
  '}',
  '.ke-pagebreak {',
  ' border:1px dotted #AAA;',
  ' font-size:0;',
  ' height:2px;',
  '}',
  '</style>'
 ];
 if (!_isArray(cssPath)) {
  cssPath = [cssPath];
 }
 _each(cssPath, function(i, path) {
  if (path) {
   arr.push('<link href="' + path + '" rel="stylesheet" />');
  }
 });
 if (cssData) {
  arr.push('<style>' + cssData + '</style>');
 }
 arr.push('</head><body ' + (bodyClass ? 'class="' + bodyClass + '"' : '') + '></body></html>');
 return arr.join('\n');
}
function _elementVal(knode, val) {
 if (knode.hasVal()) {
  if (val === undefined) {
   var html = knode.val();
   html = html.replace(/(<(?:p|p\s[^>]*)>) *(<\/p>)/ig, '');
   return html;
  }
  return knode.val(val);
 }
 return knode.html(val);
}
function KEdit(options) {
 this.init(options);
}
_extend(KEdit, KWidget, {
 init : function(options) {
  var self = this;
  KEdit.parent.init.call(self, options);
  self.srcElement = K(options.srcElement);
  self.div.addClass('ke-edit');
  self.designMode = _undef(options.designMode, true);
  self.beforeGetHtml = options.beforeGetHtml;
  self.beforeSetHtml = options.beforeSetHtml;
  self.afterSetHtml = options.afterSetHtml;
  var themesPath = _undef(options.themesPath, ''),
   bodyClass = options.bodyClass,
   cssPath = options.cssPath,
   cssData = options.cssData,
   isDocumentDomain = location.host.replace(/:\d+/, '') !== document.domain,
   srcScript = ('document.open();' +
    (isDocumentDomain ? 'document.domain="' + document.domain + '";' : '') +
    'document.close();'),
   iframeSrc = _IE ? ' src="javascript:void(function(){' + encodeURIComponent(srcScript) + '}())"' : '';
  self.iframe = K('<iframe class="ke-edit-iframe" hidefocus="true" frameborder="0"' + iframeSrc + '></iframe>').css('width', '100%');
  self.textarea = K('<textarea class="ke-edit-textarea" hidefocus="true"></textarea>').css('width', '100%');
  if (self.width) {
   self.setWidth(self.width);
  }
  if (self.height) {
   self.setHeight(self.height);
  }
  if (self.designMode) {
   self.textarea.hide();
  } else {
   self.iframe.hide();
  }
  function ready() {
   var doc = _iframeDoc(self.iframe);
   doc.open();
   if (isDocumentDomain) {
    doc.domain = document.domain;
   }
   doc.write(_getInitHtml(themesPath, bodyClass, cssPath, cssData));
   doc.close();
   self.win = self.iframe[0].contentWindow;
   self.doc = doc;
   var cmd = _cmd(doc);
   self.afterChange(function(e) {
    cmd.selection();
   });
   if (_WEBKIT) {
    K(doc).click(function(e) {
     if (K(e.target).name === 'img') {
      cmd.selection(true);
      cmd.range.selectNode(e.target);
      cmd.select();
     }
    });
   }
   if (_IE) {
    K(document).mousedown(function() {
     if (cmd.range.isControl()) {
      self.blur();
     }
    });
   }
   if (_IE) {
    K(doc).keydown(function(e) {
     if (e.which == 8) {
      cmd.selection();
      var rng = cmd.range;
      if (rng.isControl()) {
       rng.collapse(true);
       K(rng.startContainer.childNodes[rng.startOffset]).remove();
       e.preventDefault();
      }
     }
    });
   }
   self.cmd = cmd;
   self.html(_elementVal(self.srcElement));
   if (_IE) {
    doc.body.disabled = true;
    doc.body.contentEditable = true;
    doc.body.removeAttribute('disabled');
   } else {
    doc.designMode = 'on';
   }
   if (options.afterCreate) {
    options.afterCreate.call(self);
   }
  }
  if (isDocumentDomain) {
   self.iframe.bind('load', function(e) {
    self.iframe.unbind('load');
    if (_IE) {
     ready();
    } else {
     setTimeout(ready, 0);
    }
   });
  }
  self.div.append(self.iframe);
  self.div.append(self.textarea);
  self.srcElement.hide();
  !isDocumentDomain && ready();
 },
 setWidth : function(val) {
  this.div.css('width', _addUnit(val));
  return this;
 },
 setHeight : function(val) {
  var self = this;
  val = _addUnit(val);
  self.div.css('height', val);
  self.iframe.css('height', val);
  if ((_IE && _V < 8) || _QUIRKS) {
   val = _addUnit(_removeUnit(val) - 2);
  }
  self.textarea.css('height', val);
  return self;
 },
 remove : function() {
  var self = this, doc = self.doc;
  K(doc.body).unbind();
  K(doc).unbind();
  K(self.win).unbind();
  _elementVal(self.srcElement, self.html());
  self.srcElement.show();
  doc.write('');
  self.iframe.unbind();
  self.textarea.unbind();
  KEdit.parent.remove.call(self);
 },
 html : function(val, isFull) {
  var self = this, doc = self.doc;
  if (self.designMode) {
   var body = doc.body;
   if (val === undefined) {
    if (isFull) {
     val = '<!doctype html><html>' + body.parentNode.innerHTML + '</html>';
    } else {
     val = body.innerHTML;
    }
    if (self.beforeGetHtml) {
     val = self.beforeGetHtml(val);
    }
    if (_GECKO && val == '<br />') {
     val = '';
    }
    return val;
   }
   if (self.beforeSetHtml) {
    val = self.beforeSetHtml(val);
   }
   if (_IE && _V >= 9) {
    val = val.replace(/(<.*?checked=")checked(".*>)/ig, '$1$2');
   }
   K(body).html(val);
   if (self.afterSetHtml) {
    self.afterSetHtml();
   }
   return self;
  }
  if (val === undefined) {
   return self.textarea.val();
  }
  self.textarea.val(val);
  return self;
 },
 design : function(bool) {
  var self = this, val;
  if (bool === undefined ? !self.designMode : bool) {
   if (!self.designMode) {
    val = self.html();
    self.designMode = true;
    self.html(val);
    self.textarea.hide();
    self.iframe.show();
   }
  } else {
   if (self.designMode) {
    val = self.html();
    self.designMode = false;
    self.html(val);
    self.iframe.hide();
    self.textarea.show();
   }
  }
  return self.focus();
 },
 focus : function() {
  var self = this;
  self.designMode ? self.win.focus() : self.textarea[0].focus();
  return self;
 },
 blur : function() {
  var self = this;
  if (_IE) {
   var input = K('<input type="text" style="float:left;width:0;height:0;padding:0;margin:0;border:0;" value="" />', self.div);
   self.div.append(input);
   input[0].focus();
   input.remove();
  } else {
   self.designMode ? self.win.blur() : self.textarea[0].blur();
  }
  return self;
 },
 afterChange : function(fn) {
  var self = this, doc = self.doc, body = doc.body;
  K(doc).keyup(function(e) {
   if (!e.ctrlKey && !e.altKey && _CHANGE_KEY_MAP[e.which]) {
    fn(e);
   }
  });
  K(doc).mouseup(fn).contextmenu(fn);
  K(self.win).blur(fn);
  function timeoutHandler(e) {
   setTimeout(function() {
    fn(e);
   }, 1);
  }
  K(body).bind('paste', timeoutHandler);
  K(body).bind('cut', timeoutHandler);
  return self;
 }
});
function _edit(options) {
 return new KEdit(options);
}
K.EditClass = KEdit;
K.edit = _edit;
K.iframeDoc = _iframeDoc;
function _selectToolbar(name, fn) {
 var self = this,
  knode = self.get(name);
 if (knode) {
  if (knode.hasClass('ke-disabled')) {
   return;
  }
  fn(knode);
 }
}
function KToolbar(options) {
 this.init(options);
}
_extend(KToolbar, KWidget, {
 init : function(options) {
  var self = this;
  KToolbar.parent.init.call(self, options);
  self.disableMode = _undef(options.disableMode, false);
  self.noDisableItemMap = _toMap(_undef(options.noDisableItems, []));
  self._itemMap = {};
  self.div.addClass('ke-toolbar').bind('contextmenu,mousedown,mousemove', function(e) {
   e.preventDefault();
  }).attr('unselectable', 'on');
  function find(target) {
   var knode = K(target);
   if (knode.hasClass('ke-outline')) {
    return knode;
   }
   if (knode.hasClass('ke-toolbar-icon')) {
    return knode.parent();
   }
  }
  function hover(e, method) {
   var knode = find(e.target);
   if (knode) {
    if (knode.hasClass('ke-disabled')) {
     return;
    }
    if (knode.hasClass('ke-selected')) {
     return;
    }
    knode[method]('ke-on');
   }
  }
  self.div.mouseover(function(e) {
   hover(e, 'addClass');
  })
  .mouseout(function(e) {
   hover(e, 'removeClass');
  })
  .click(function(e) {
   var knode = find(e.target);
   if (knode) {
    if (knode.hasClass('ke-disabled')) {
     return;
    }
    self.options.click.call(this, e, knode.attr('data-name'));
   }
  });
 },
 get : function(name) {
  if (this._itemMap[name]) {
   return this._itemMap[name];
  }
  return (this._itemMap[name] = K('span.ke-icon-' + name, this.div).parent());
 },
 select : function(name) {
  _selectToolbar.call(this, name, function(knode) {
   knode.addClass('ke-selected');
  });
  return self;
 },
 unselect : function(name) {
  _selectToolbar.call(this, name, function(knode) {
   knode.removeClass('ke-selected').removeClass('ke-on');
  });
  return self;
 },
 enable : function(name) {
  var self = this,
   knode = name.get ? name : self.get(name);
  if (knode) {
   knode.removeClass('ke-disabled');
   knode.opacity(1);
  }
  return self;
 },
 disable : function(name) {
  var self = this,
   knode = name.get ? name : self.get(name);
  if (knode) {
   knode.removeClass('ke-selected').addClass('ke-disabled');
   knode.opacity(0.5);
  }
  return self;
 },
 disableAll : function(bool, noDisableItems) {
  var self = this, map = self.noDisableItemMap, item;
  if (noDisableItems) {
   map = _toMap(noDisableItems);
  }
  if (bool === undefined ? !self.disableMode : bool) {
   K('span.ke-outline', self.div).each(function() {
    var knode = K(this),
     name = knode[0].getAttribute('data-name', 2);
    if (!map[name]) {
     self.disable(knode);
    }
   });
   self.disableMode = true;
  } else {
   K('span.ke-outline', self.div).each(function() {
    var knode = K(this),
     name = knode[0].getAttribute('data-name', 2);
    if (!map[name]) {
     self.enable(knode);
    }
   });
   self.disableMode = false;
  }
  return self;
 }
});
function _toolbar(options) {
 return new KToolbar(options);
}
K.ToolbarClass = KToolbar;
K.toolbar = _toolbar;
function KMenu(options) {
 this.init(options);
}
_extend(KMenu, KWidget, {
 init : function(options) {
  var self = this;
  options.z = options.z || 811213;
  KMenu.parent.init.call(self, options);
  self.centerLineMode = _undef(options.centerLineMode, true);
  self.div.addClass('ke-menu').bind('click,mousedown', function(e){
   e.stopPropagation();
  }).attr('unselectable', 'on');
 },
 addItem : function(item) {
  var self = this;
  if (item.title === '-') {
   self.div.append(K('<div class="ke-menu-separator"></div>'));
   return;
  }
  var itemDiv = K('<div class="ke-menu-item" unselectable="on"></div>'),
   leftDiv = K('<div class="ke-inline-block ke-menu-item-left"></div>'),
   rightDiv = K('<div class="ke-inline-block ke-menu-item-right"></div>'),
   height = _addUnit(item.height),
   iconClass = _undef(item.iconClass, '');
  self.div.append(itemDiv);
  if (height) {
   itemDiv.css('height', height);
   rightDiv.css('line-height', height);
  }
  var centerDiv;
  if (self.centerLineMode) {
   centerDiv = K('<div class="ke-inline-block ke-menu-item-center"></div>');
   if (height) {
    centerDiv.css('height', height);
   }
  }
  itemDiv.mouseover(function(e) {
   K(this).addClass('ke-menu-item-on');
   if (centerDiv) {
    centerDiv.addClass('ke-menu-item-center-on');
   }
  })
  .mouseout(function(e) {
   K(this).removeClass('ke-menu-item-on');
   if (centerDiv) {
    centerDiv.removeClass('ke-menu-item-center-on');
   }
  })
  .click(function(e) {
   item.click.call(K(this));
   e.stopPropagation();
  })
  .append(leftDiv);
  if (centerDiv) {
   itemDiv.append(centerDiv);
  }
  itemDiv.append(rightDiv);
  if (item.checked) {
   iconClass = 'ke-icon-checked';
  }
  if (iconClass !== '') {
   leftDiv.html('<span class="ke-inline-block ke-toolbar-icon ke-toolbar-icon-url ' + iconClass + '"></span>');
  }
  rightDiv.html(item.title);
  return self;
 },
 remove : function() {
  var self = this;
  if (self.options.beforeRemove) {
   self.options.beforeRemove.call(self);
  }
  K('.ke-menu-item', self.div[0]).unbind();
  KMenu.parent.remove.call(self);
  return self;
 }
});
function _menu(options) {
 return new KMenu(options);
}
K.MenuClass = KMenu;
K.menu = _menu;
function KColorPicker(options) {
 this.init(options);
}
_extend(KColorPicker, KWidget, {
 init : function(options) {
  var self = this;
  options.z = options.z || 811213;
  KColorPicker.parent.init.call(self, options);
  var colors = options.colors || [
   ['#E53333', '#E56600', '#FF9900', '#64451D', '#DFC5A4', '#FFE500'],
   ['#009900', '#006600', '#99BB00', '#B8D100', '#60D978', '#00D5FF'],
   ['#337FE5', '#003399', '#4C33E5', '#9933E5', '#CC33E5', '#EE33EE'],
   ['#FFFFFF', '#CCCCCC', '#999999', '#666666', '#333333', '#000000']
  ];
  self.selectedColor = (options.selectedColor || '').toLowerCase();
  self._cells = [];
  self.div.addClass('ke-colorpicker').bind('click,mousedown', function(e){
   e.stopPropagation();
  }).attr('unselectable', 'on');
  var table = self.doc.createElement('table');
  self.div.append(table);
  table.className = 'ke-colorpicker-table';
  table.cellPadding = 0;
  table.cellSpacing = 0;
  table.border = 0;
  var row = table.insertRow(0), cell = row.insertCell(0);
  cell.colSpan = colors[0].length;
  self._addAttr(cell, '', 'ke-colorpicker-cell-top');
  for (var i = 0; i < colors.length; i++) {
   row = table.insertRow(i + 1);
   for (var j = 0; j < colors[i].length; j++) {
    cell = row.insertCell(j);
    self._addAttr(cell, colors[i][j], 'ke-colorpicker-cell');
   }
  }
 },
 _addAttr : function(cell, color, cls) {
  var self = this;
  cell = K(cell).addClass(cls);
  if (self.selectedColor === color.toLowerCase()) {
   cell.addClass('ke-colorpicker-cell-selected');
  }
  cell.attr('title', color || self.options.noColor);
  cell.mouseover(function(e) {
   K(this).addClass('ke-colorpicker-cell-on');
  });
  cell.mouseout(function(e) {
   K(this).removeClass('ke-colorpicker-cell-on');
  });
  cell.click(function(e) {
   e.stop();
   self.options.click.call(K(this), color);
  });
  if (color) {
   cell.append(K('<div class="ke-colorpicker-cell-color" unselectable="on"></div>').css('background-color', color));
  } else {
   cell.html(self.options.noColor);
  }
  K(cell).attr('unselectable', 'on');
  self._cells.push(cell);
 },
 remove : function() {
  var self = this;
  _each(self._cells, function() {
   this.unbind();
  });
  KColorPicker.parent.remove.call(self);
  return self;
 }
});
function _colorpicker(options) {
 return new KColorPicker(options);
}
K.ColorPickerClass = KColorPicker;
K.colorpicker = _colorpicker;
function KUploadButton(options) {
 this.init(options);
}
_extend(KUploadButton, {
 init : function(options) {
  var self = this,
   button = K(options.button),
   fieldName = options.fieldName || 'file',
   url = options.url || '',
   title = button.val(),
   extraParams = options.extraParams || {},
   cls = button[0].className || '',
   target = options.target || 'kindeditor_upload_iframe_' + new Date().getTime();
  options.afterError = options.afterError || function(str) {
   alert(str);
  };
  var hiddenElements = [];
  for(var k in extraParams){
   hiddenElements.push('<input type="hidden" name="' + k + '" value="' + extraParams[k] + '" />');
  }
  var html = [
   '<div class="ke-inline-block ' + cls + '">',
   (options.target ? '' : '<iframe name="' + target + '" style="display:none;"></iframe>'),
   (options.form ? '<div class="ke-upload-area">' : '<form class="ke-upload-area ke-form" method="post" enctype="multipart/form-data" target="' + target + '" action="' + url + '">'),
   '<span class="ke-button-common">',
   hiddenElements.join(''),
   '<input type="button" class="ke-button-common ke-button" value="' + title + '" />',
   '</span>',
   '<input type="file" class="ke-upload-file" name="' + fieldName + '" tabindex="-1" />',
   (options.form ? '</div>' : '</form>'),
   '</div>'].join('');
  var div = K(html, button.doc);
  button.hide();
  button.before(div);
  self.div = div;
  self.button = button;
  self.iframe = options.target ? K('iframe[name="' + target + '"]') : K('iframe', div);
  self.form = options.form ? K(options.form) : K('form', div);
  var width = options.width || K('.ke-button-common', div).width();
  self.fileBox = K('.ke-upload-file', div).width(width);
  self.options = options;
 },
 submit : function() {
  var self = this,
   iframe = self.iframe;
  iframe.bind('load', function() {
   iframe.unbind();
   var tempForm = document.createElement('form');
   self.fileBox.before(tempForm);
   K(tempForm).append(self.fileBox);
   tempForm.reset();
   K(tempForm).remove(true);
   var doc = K.iframeDoc(iframe),
    pre = doc.getElementsByTagName('pre')[0],
    str = '', data;
   if (pre) {
    str = pre.innerHTML;
   } else {
    str = doc.body.innerHTML;
   }
   iframe[0].src = 'javascript:false';
   try {
    data = K.json(str);
   } catch (e) {
    self.options.afterError.call(self, '<!doctype html><html>' + doc.body.parentNode.innerHTML + '</html>');
   }
   if (data) {
    self.options.afterUpload.call(self, data);
   }
  });
  self.form[0].submit();
  return self;
 },
 remove : function() {
  var self = this;
  if (self.fileBox) {
   self.fileBox.unbind();
  }
  self.iframe.remove();
  self.div.remove();
  self.button.show();
  return self;
 }
});
function _uploadbutton(options) {
 return new KUploadButton(options);
}
K.UploadButtonClass = KUploadButton;
K.uploadbutton = _uploadbutton;
function _createButton(arg) {
 arg = arg || {};
 var name = arg.name || '',
  span = K('<span class="ke-button-common ke-button-outer" title="' + name + '"></span>'),
  btn = K('<input class="ke-button-common ke-button" type="button" value="' + name + '" />');
 if (arg.click) {
  btn.click(arg.click);
 }
 span.append(btn);
 return span;
}
function KDialog(options) {
 this.init(options);
}
_extend(KDialog, KWidget, {
 init : function(options) {
  var self = this;
  var shadowMode = _undef(options.shadowMode, true);
  options.z = options.z || 811213;
  options.shadowMode = false;
  options.autoScroll = _undef(options.autoScroll, true);
  KDialog.parent.init.call(self, options);
  var title = options.title,
   body = K(options.body, self.doc),
   previewBtn = options.previewBtn,
   yesBtn = options.yesBtn,
   noBtn = options.noBtn,
   closeBtn = options.closeBtn,
   showMask = _undef(options.showMask, true);
  self.div.addClass('ke-dialog').bind('click,mousedown', function(e){
   e.stopPropagation();
  });
  var contentDiv = K('<div class="ke-dialog-content"></div>').appendTo(self.div);
  if (_IE && _V < 7) {
   self.iframeMask = K('<iframe src="about:blank" class="ke-dialog-shadow"></iframe>').appendTo(self.div);
  } else if (shadowMode) {
   K('<div class="ke-dialog-shadow"></div>').appendTo(self.div);
  }
  var headerDiv = K('<div class="ke-dialog-header"></div>');
  contentDiv.append(headerDiv);
  headerDiv.html(title);
  self.closeIcon = K('<span class="ke-dialog-icon-close" title="' + closeBtn.name + '"></span>').click(closeBtn.click);
  headerDiv.append(self.closeIcon);
  self.draggable({
   clickEl : headerDiv,
   beforeDrag : options.beforeDrag
  });
  var bodyDiv = K('<div class="ke-dialog-body"></div>');
  contentDiv.append(bodyDiv);
  bodyDiv.append(body);
  var footerDiv = K('<div class="ke-dialog-footer"></div>');
  if (previewBtn || yesBtn || noBtn) {
   contentDiv.append(footerDiv);
  }
  _each([
   { btn : previewBtn, name : 'preview' },
   { btn : yesBtn, name : 'yes' },
   { btn : noBtn, name : 'no' }
  ], function() {
   if (this.btn) {
    var button = _createButton(this.btn);
    button.addClass('ke-dialog-' + this.name);
    footerDiv.append(button);
   }
  });
  if (self.height) {
   bodyDiv.height(_removeUnit(self.height) - headerDiv.height() - footerDiv.height());
  }
  self.div.width(self.div.width());
  self.div.height(self.div.height());
  self.mask = null;
  if (showMask) {
   var docEl = _docElement(self.doc),
    docWidth = Math.max(docEl.scrollWidth, docEl.clientWidth),
    docHeight = Math.max(docEl.scrollHeight, docEl.clientHeight);
   self.mask = _widget({
    x : 0,
    y : 0,
    z : self.z - 1,
    cls : 'ke-dialog-mask',
    width : docWidth,
    height : docHeight
   });
  }
  self.autoPos(self.div.width(), self.div.height());
  self.footerDiv = footerDiv;
  self.bodyDiv = bodyDiv;
  self.headerDiv = headerDiv;
  self.isLoading = false;
 },
 setMaskIndex : function(z) {
  var self = this;
  self.mask.div.css('z-index', z);
 },
 showLoading : function(msg) {
  msg = _undef(msg, '');
  var self = this, body = self.bodyDiv;
  self.loading = K('<div class="ke-dialog-loading"><div class="ke-inline-block ke-dialog-loading-content" style="margin-top:' + Math.round(body.height() / 3) + 'px;">' + msg + '</div></div>')
   .width(body.width()).height(body.height())
   .css('top', self.headerDiv.height() + 'px');
  body.css('visibility', 'hidden').after(self.loading);
  self.isLoading = true;
  return self;
 },
 hideLoading : function() {
  this.loading && this.loading.remove();
  this.bodyDiv.css('visibility', 'visible');
  this.isLoading = false;
  return this;
 },
 remove : function() {
  var self = this;
  if (self.options.beforeRemove) {
   self.options.beforeRemove.call(self);
  }
  self.mask && self.mask.remove();
  self.iframeMask && self.iframeMask.remove();
  self.closeIcon.unbind();
  K('input', self.div).unbind();
  K('button', self.div).unbind();
  self.footerDiv.unbind();
  self.bodyDiv.unbind();
  self.headerDiv.unbind();
  K('iframe', self.div).each(function() {
   K(this).remove();
  });
  KDialog.parent.remove.call(self);
  return self;
 }
});
function _dialog(options) {
 return new KDialog(options);
}
K.DialogClass = KDialog;
K.dialog = _dialog;
function _tabs(options) {
 var self = _widget(options),
  remove = self.remove,
  afterSelect = options.afterSelect,
  div = self.div,
  liList = [];
 div.addClass('ke-tabs')
  .bind('contextmenu,mousedown,mousemove', function(e) {
   e.preventDefault();
  });
 var ul = K('<ul class="ke-tabs-ul ke-clearfix"></ul>');
 div.append(ul);
 self.add = function(tab) {
  var li = K('<li class="ke-tabs-li">' + tab.title + '</li>');
  li.data('tab', tab);
  liList.push(li);
  ul.append(li);
 };
 self.selectedIndex = 0;
 self.select = function(index) {
  self.selectedIndex = index;
  _each(liList, function(i, li) {
   li.unbind();
   if (i === index) {
    li.addClass('ke-tabs-li-selected');
    K(li.data('tab').panel).show('');
   } else {
    li.removeClass('ke-tabs-li-selected').removeClass('ke-tabs-li-on')
    .mouseover(function() {
     K(this).addClass('ke-tabs-li-on');
    })
    .mouseout(function() {
     K(this).removeClass('ke-tabs-li-on');
    })
    .click(function() {
     self.select(i);
    });
    K(li.data('tab').panel).hide();
   }
  });
  if (afterSelect) {
   afterSelect.call(self, index);
  }
 };
 self.remove = function() {
  _each(liList, function() {
   this.remove();
  });
  ul.remove();
  remove.call(self);
 };
 return self;
}
K.tabs = _tabs;
function _loadScript(url, fn) {
 var head = document.getElementsByTagName('head')[0] || (_QUIRKS ? document.body : document.documentElement),
  script = document.createElement('script');
 head.appendChild(script);
 script.src = url;
 script.charset = 'utf-8';
 script.onload = script.onreadystatechange = function() {
  if (!this.readyState || this.readyState === 'loaded') {
   if (fn) {
    fn();
   }
   script.onload = script.onreadystatechange = null;
   head.removeChild(script);
  }
 };
}
function _chopQuery(url) {
 var index = url.indexOf('?');
 return index > 0 ? url.substr(0, index) : url;
}
function _loadStyle(url) {
 var head = document.getElementsByTagName('head')[0] || (_QUIRKS ? document.body : document.documentElement),
  link = document.createElement('link'),
  absoluteUrl = _chopQuery(_formatUrl(url, 'absolute'));
 var links = K('link[rel="stylesheet"]', head);
 for (var i = 0, len = links.length; i < len; i++) {
  if (_chopQuery(_formatUrl(links[i].href, 'absolute')) === absoluteUrl) {
   return;
  }
 }
 head.appendChild(link);
 link.href = url;
 link.rel = 'stylesheet';
}
function _ajax(url, fn, method, param, dataType) {
 method = method || 'GET';
 dataType = dataType || 'json';
 var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
 xhr.open(method, url, true);
 xhr.onreadystatechange = function () {
  if (xhr.readyState == 4 && xhr.status == 200) {
   if (fn) {
    var data = _trim(xhr.responseText);
    if (dataType == 'json') {
     data = _json(data);
    }
    fn(data);
   }
  }
 };
 if (method == 'POST') {
  var params = [];
  _each(param, function(key, val) {
   params.push(encodeURIComponent(key) + '=' + encodeURIComponent(val));
  });
  try {
   xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  } catch (e) {}
  xhr.send(params.join('&'));
 } else {
  xhr.send(null);
 }
}
K.loadScript = _loadScript;
K.loadStyle = _loadStyle;
K.ajax = _ajax;
var _plugins = {};
function _plugin(name, fn) {
 if (name === undefined) {
  return _plugins;
 }
 if (!fn) {
  return _plugins[name];
 }
 _plugins[name] = fn;
}
var _language = {};
function _parseLangKey(key) {
 var match, ns = 'core';
 if ((match = /^(\w+)\.(\w+)$/.exec(key))) {
  ns = match[1];
  key = match[2];
 }
 return { ns : ns, key : key };
}
function _lang(mixed, langType) {
 langType = langType === undefined ? K.options.langType : langType;
 if (typeof mixed === 'string') {
  if (!_language[langType]) {
   return 'no language';
  }
  var pos = mixed.length - 1;
  if (mixed.substr(pos) === '.') {
   return _language[langType][mixed.substr(0, pos)];
  }
  var obj = _parseLangKey(mixed);
  return _language[langType][obj.ns][obj.key];
 }
 _each(mixed, function(key, val) {
  var obj = _parseLangKey(key);
  if (!_language[langType]) {
   _language[langType] = {};
  }
  if (!_language[langType][obj.ns]) {
   _language[langType][obj.ns] = {};
  }
  _language[langType][obj.ns][obj.key] = val;
 });
}
function _getImageFromRange(range, fn) {
 if (range.collapsed) {
  return;
 }
 range = range.cloneRange().up();
 var sc = range.startContainer, so = range.startOffset;
 if (!_WEBKIT && !range.isControl()) {
  return;
 }
 var img = K(sc.childNodes[so]);
 if (!img || img.name != 'img') {
  return;
 }
 if (fn(img)) {
  return img;
 }
}
function _bindContextmenuEvent() {
 var self = this, doc = self.edit.doc;
 K(doc).contextmenu(function(e) {
  if (self.menu) {
   self.hideMenu();
  }
  if (!self.useContextmenu) {
   e.preventDefault();
   return;
  }
  if (self._contextmenus.length === 0) {
   return;
  }
  var maxWidth = 0, items = [];
  _each(self._contextmenus, function() {
   if (this.title == '-') {
    items.push(this);
    return;
   }
   if (this.cond && this.cond()) {
    items.push(this);
    if (this.width && this.width > maxWidth) {
     maxWidth = this.width;
    }
   }
  });
  while (items.length > 0 && items[0].title == '-') {
   items.shift();
  }
  while (items.length > 0 && items[items.length - 1].title == '-') {
   items.pop();
  }
  var prevItem = null;
  _each(items, function(i) {
   if (this.title == '-' && prevItem.title == '-') {
    delete items[i];
   }
   prevItem = this;
  });
  if (items.length > 0) {
   e.preventDefault();
   var pos = K(self.edit.iframe).pos(),
    menu = _menu({
     x : pos.x + e.clientX,
     y : pos.y + e.clientY,
     width : maxWidth,
     css : { visibility: 'hidden' },
     shadowMode : self.shadowMode
    });
   _each(items, function() {
    if (this.title) {
     menu.addItem(this);
    }
   });
   var docEl = _docElement(menu.doc),
    menuHeight = menu.div.height();
   if (e.clientY + menuHeight >= docEl.clientHeight - 100) {
    menu.pos(menu.x, _removeUnit(menu.y) - menuHeight);
   }
   menu.div.css('visibility', 'visible');
   self.menu = menu;
  }
 });
}
function _bindNewlineEvent() {
 var self = this, doc = self.edit.doc, newlineTag = self.newlineTag;
 if (_IE && newlineTag !== 'br') {
  return;
 }
 if (_GECKO && _V < 3 && newlineTag !== 'p') {
  return;
 }
 if (_OPERA && _V < 9) {
  return;
 }
 var brSkipTagMap = _toMap('h1,h2,h3,h4,h5,h6,pre,li'),
  pSkipTagMap = _toMap('p,h1,h2,h3,h4,h5,h6,pre,li,blockquote');
 function getAncestorTagName(range) {
  var ancestor = K(range.commonAncestor());
  while (ancestor) {
   if (ancestor.type == 1 && !ancestor.isStyle()) {
    break;
   }
   ancestor = ancestor.parent();
  }
  return ancestor.name;
 }
 K(doc).keydown(function(e) {
  if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) {
   return;
  }
  self.cmd.selection();
  var tagName = getAncestorTagName(self.cmd.range);
  if (tagName == 'marquee' || tagName == 'select') {
   return;
  }
  if (newlineTag === 'br' && !brSkipTagMap[tagName]) {
   e.preventDefault();
   self.insertHtml('<br />' + (_IE && _V < 9 ? '' : '\u200B'));
   return;
  }
  if (!pSkipTagMap[tagName]) {
   _nativeCommand(doc, 'formatblock', '<p>');
  }
 });
 K(doc).keyup(function(e) {
  if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) {
   return;
  }
  if (newlineTag == 'br') {
   return;
  }
  if (_GECKO) {
   var root = self.cmd.commonAncestor('p');
   var a = self.cmd.commonAncestor('a');
   if (a && a.text() == '') {
    a.remove(true);
    self.cmd.range.selectNodeContents(root[0]).collapse(true);
    self.cmd.select();
   }
   return;
  }
  self.cmd.selection();
  var tagName = getAncestorTagName(self.cmd.range);
  if (tagName == 'marquee' || tagName == 'select') {
   return;
  }
  if (!pSkipTagMap[tagName]) {
   _nativeCommand(doc, 'formatblock', '<p>');
  }
  var div = self.cmd.commonAncestor('div');
  if (div) {
   var p = K('<p></p>'),
    child = div[0].firstChild;
   while (child) {
    var next = child.nextSibling;
    p.append(child);
    child = next;
   }
   div.before(p);
   div.remove();
   self.cmd.range.selectNodeContents(p[0]);
   self.cmd.select();
  }
 });
}
function _bindTabEvent() {
 var self = this, doc = self.edit.doc;
 K(doc).keydown(function(e) {
  if (e.which == 9) {
   e.preventDefault();
   if (self.afterTab) {
    self.afterTab.call(self, e);
    return;
   }
   var cmd = self.cmd, range = cmd.range;
   range.shrink();
   if (range.collapsed && range.startContainer.nodeType == 1) {
    range.insertNode(K('@&nbsp;', doc)[0]);
    cmd.select();
   }
   self.insertHtml('&nbsp;&nbsp;&nbsp;&nbsp;');
  }
 });
}
function _bindFocusEvent() {
 var self = this;
 K(self.edit.textarea[0], self.edit.win).focus(function(e) {
  if (self.afterFocus) {
   self.afterFocus.call(self, e);
  }
 }).blur(function(e) {
  if (self.afterBlur) {
   self.afterBlur.call(self, e);
  }
 });
}
function _removeBookmarkTag(html) {
 return _trim(html.replace(/<span [^>]*id="?__kindeditor_bookmark_\w+_\d+__"?[^>]*><\/span>/ig, ''));
}
function _removeTempTag(html) {
 return html.replace(/<div[^>]+class="?__kindeditor_paste__"?[^>]*>[\s\S]*?<\/div>/ig, '');
}
function _addBookmarkToStack(stack, bookmark) {
 if (stack.length === 0) {
  stack.push(bookmark);
  return;
 }
 var prev = stack[stack.length - 1];
 if (_removeBookmarkTag(bookmark.html) !== _removeBookmarkTag(prev.html)) {
  stack.push(bookmark);
 }
}
function _undoToRedo(fromStack, toStack) {
 var self = this, edit = self.edit,
  body = edit.doc.body,
  range, bookmark;
 if (fromStack.length === 0) {
  return self;
 }
 if (edit.designMode) {
  range = self.cmd.range;
  bookmark = range.createBookmark(true);
  bookmark.html = body.innerHTML;
 } else {
  bookmark = {
   html : body.innerHTML
  };
 }
 _addBookmarkToStack(toStack, bookmark);
 var prev = fromStack.pop();
 if (_removeBookmarkTag(bookmark.html) === _removeBookmarkTag(prev.html) && fromStack.length > 0) {
  prev = fromStack.pop();
 }
 if (edit.designMode) {
  edit.html(prev.html);
  if (prev.start) {
   range.moveToBookmark(prev);
   self.select();
  }
 } else {
  K(body).html(_removeBookmarkTag(prev.html));
 }
 return self;
}
function KEditor(options) {
 var self = this;
 self.options = {};
 function setOption(key, val) {
  if (KEditor.prototype[key] === undefined) {
   self[key] = val;
  }
  self.options[key] = val;
 }
 _each(options, function(key, val) {
  setOption(key, options[key]);
 });
 _each(K.options, function(key, val) {
  if (self[key] === undefined) {
   setOption(key, val);
  }
 });
 var se = K(self.srcElement || '<textarea/>');
 if (!self.width) {
  self.width = se[0].style.width || se.width();
 }
 if (!self.height) {
  self.height = se[0].style.height || se.height();
 }
 setOption('width', _undef(self.width, self.minWidth));
 setOption('height', _undef(self.height, self.minHeight));
 setOption('width', _addUnit(self.width));
 setOption('height', _addUnit(self.height));
 if (_MOBILE && (!_IOS || _V < 534)) {
  self.designMode = false;
 }
 self.srcElement = se;
 self.initContent = '';
 self.plugin = {};
 self.isCreated = false;
 self.isLoading = false;
 self._handlers = {};
 self._contextmenus = [];
 self._undoStack = [];
 self._redoStack = [];
 self._calledPlugins = {};
 self._firstAddBookmark = true;
 self.menu = self.contextmenu = null;
 self.dialogs = [];
}
KEditor.prototype = {
 lang : function(mixed) {
  return _lang(mixed, this.langType);
 },
 loadPlugin : function(name, fn) {
  var self = this;
  if (_plugins[name]) {
   if (self._calledPlugins[name]) {
    if (fn) {
     fn.call(self);
    }
    return self;
   }
   _plugins[name].call(self, KindEditor);
   if (fn) {
    fn.call(self);
   }
   self._calledPlugins[name] = true;
   return self;
  }
  if (self.isLoading) {
   return self;
  }
  self.isLoading = true;
  _loadScript(self.pluginsPath + name + '/' + name + '.js?ver=' + encodeURIComponent(K.DEBUG ? _TIME : _VERSION), function() {
   self.isLoading = false;
   if (_plugins[name]) {
    self.loadPlugin(name, fn);
   }
  });
  return self;
 },
 handler : function(key, fn) {
  var self = this;
  if (!self._handlers[key]) {
   self._handlers[key] = [];
  }
  if (_isFunction(fn)) {
   self._handlers[key].push(fn);
   return self;
  }
  _each(self._handlers[key], function() {
   fn = this.call(self, fn);
  });
  return fn;
 },
 clickToolbar : function(name, fn) {
  var self = this, key = 'clickToolbar' + name;
  if (fn === undefined) {
   if (self._handlers[key]) {
    return self.handler(key);
   }
   self.loadPlugin(name, function() {
    self.handler(key);
   });
   return self;
  }
  return self.handler(key, fn);
 },
 updateState : function() {
  var self = this;
  _each(('justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,insertunorderedlist,' +
   'subscript,superscript,bold,italic,underline,strikethrough').split(','), function(i, name) {
   self.cmd.state(name) ? self.toolbar.select(name) : self.toolbar.unselect(name);
  });
  return self;
 },
 addContextmenu : function(item) {
  this._contextmenus.push(item);
  return this;
 },
 afterCreate : function(fn) {
  return this.handler('afterCreate', fn);
 },
 beforeRemove : function(fn) {
  return this.handler('beforeRemove', fn);
 },
 beforeGetHtml : function(fn) {
  return this.handler('beforeGetHtml', fn);
 },
 beforeSetHtml : function(fn) {
  return this.handler('beforeSetHtml', fn);
 },
 afterSetHtml : function(fn) {
  return this.handler('afterSetHtml', fn);
 },
 create : function() {
  var self = this, fullscreenMode = self.fullscreenMode;
  if (self.isCreated) {
   return self;
  }
  if (self.srcElement.data('kindeditor')) {
   return self;
  }
  self.srcElement.data('kindeditor', 'true');
  if (fullscreenMode) {
   _docElement().style.overflow = 'hidden';
  } else {
   _docElement().style.overflow = '';
  }
  var width = fullscreenMode ? _docElement().clientWidth + 'px' : self.width,
   height = fullscreenMode ? _docElement().clientHeight + 'px' : self.height;
  if ((_IE && _V < 8) || _QUIRKS) {
   height = _addUnit(_removeUnit(height) + 2);
  }
  var container = self.container = K(self.layout);
  if (fullscreenMode) {
   K(document.body).append(container);
  } else {
   self.srcElement.before(container);
  }
  var toolbarDiv = K('.toolbar', container),
   editDiv = K('.edit', container),
   statusbar = self.statusbar = K('.statusbar', container);
  container.removeClass('container')
   .addClass('ke-container ke-container-' + self.themeType).css('width', width);
  if (fullscreenMode) {
   container.css({
    position : 'absolute',
    left : 0,
    top : 0,
    'z-index' : 811211
   });
   if (!_GECKO) {
    self._scrollPos = _getScrollPos();
   }
   window.scrollTo(0, 0);
   K(document.body).css({
    'height' : '1px',
    'overflow' : 'hidden'
   });
   K(document.body.parentNode).css('overflow', 'hidden');
   self._fullscreenExecuted = true;
  } else {
   if (self._fullscreenExecuted) {
    K(document.body).css({
     'height' : '',
     'overflow' : ''
    });
    K(document.body.parentNode).css('overflow', '');
   }
   if (self._scrollPos) {
    window.scrollTo(self._scrollPos.x, self._scrollPos.y);
   }
  }
  var htmlList = [];
  K.each(self.items, function(i, name) {
   if (name == '|') {
    htmlList.push('<span class="ke-inline-block ke-separator"></span>');
   } else if (name == '/') {
    htmlList.push('<div class="ke-hr"></div>');
   } else {
    htmlList.push('<span class="ke-outline" data-name="' + name + '" title="' + self.lang(name) + '" unselectable="on">');
    htmlList.push('<span class="ke-toolbar-icon ke-toolbar-icon-url ke-icon-' + name + '" unselectable="on"></span></span>');
   }
  });
  var toolbar = self.toolbar = _toolbar({
   src : toolbarDiv,
   html : htmlList.join(''),
   noDisableItems : self.noDisableItems,
   click : function(e, name) {
    e.stop();
    if (self.menu) {
     var menuName = self.menu.name;
     self.hideMenu();
     if (menuName === name) {
      return;
     }
    }
    self.clickToolbar(name);
   }
  });
  var editHeight = _removeUnit(height) - toolbar.div.height();
  var edit = self.edit = _edit({
   height : editHeight > 0 && _removeUnit(height) > self.minHeight ? editHeight : self.minHeight,
   src : editDiv,
   srcElement : self.srcElement,
   designMode : self.designMode,
   themesPath : self.themesPath,
   bodyClass : self.bodyClass,
   cssPath : self.cssPath,
   cssData : self.cssData,
   beforeGetHtml : function(html) {
    html = self.beforeGetHtml(html);
    return _formatHtml(html, self.filterMode ? self.htmlTags : null, self.urlType, self.wellFormatMode, self.indentChar);
   },
   beforeSetHtml : function(html) {
    html = _formatHtml(html, self.filterMode ? self.htmlTags : null, '', false);
    return self.beforeSetHtml(html);
   },
   afterSetHtml : function() {
    self.edit = edit = this;
    self.afterSetHtml();
   },
   afterCreate : function() {
    self.edit = edit = this;
    self.cmd = edit.cmd;
    self._docMousedownFn = function(e) {
     if (self.menu) {
      self.hideMenu();
     }
    };
    K(edit.doc, document).mousedown(self._docMousedownFn);
    _bindContextmenuEvent.call(self);
    _bindNewlineEvent.call(self);
    _bindTabEvent.call(self);
    _bindFocusEvent.call(self);
    edit.afterChange(function(e) {
     if (!edit.designMode) {
      return;
     }
     self.updateState();
     self.addBookmark();
     if (self.options.afterChange) {
      self.options.afterChange.call(self);
     }
    });
    edit.textarea.keyup(function(e) {
     if (!e.ctrlKey && !e.altKey && _INPUT_KEY_MAP[e.which]) {
      if (self.options.afterChange) {
       self.options.afterChange.call(self);
      }
     }
    });
    if (self.readonlyMode) {
     self.readonly();
    }
    self.isCreated = true;
    if (self.initContent === '') {
     self.initContent = self.html();
    }
    self.afterCreate();
    if (self.options.afterCreate) {
     self.options.afterCreate.call(self);
    }
   }
  });
  statusbar.removeClass('statusbar').addClass('ke-statusbar')
   .append('<span class="ke-inline-block ke-statusbar-center-icon"></span>')
   .append('<span class="ke-inline-block ke-statusbar-right-icon"></span>');
  K(window).unbind('resize');
  function initResize() {
   if (statusbar.height() === 0) {
    setTimeout(initResize, 100);
    return;
   }
   self.resize(width, height);
  }
  initResize();
  function newResize(width, height, updateProp) {
   updateProp = _undef(updateProp, true);
   if (width && width >= self.minWidth) {
    self.resize(width, null);
    if (updateProp) {
     self.width = _addUnit(width);
    }
   }
   if (height && height >= self.minHeight) {
    self.resize(null, height);
    if (updateProp) {
     self.height = _addUnit(height);
    }
   }
  }
  if (fullscreenMode) {
   K(window).bind('resize', function(e) {
    if (self.isCreated) {
     newResize(_docElement().clientWidth, _docElement().clientHeight, false);
    }
   });
   toolbar.select('fullscreen');
   statusbar.first().css('visibility', 'hidden');
   statusbar.last().css('visibility', 'hidden');
  } else {
   if (_GECKO) {
    K(window).bind('scroll', function(e) {
     self._scrollPos = _getScrollPos();
    });
   }
   if (self.resizeType > 0) {
    _drag({
     moveEl : container,
     clickEl : statusbar,
     moveFn : function(x, y, width, height, diffX, diffY) {
      height += diffY;
      newResize(null, height);
     }
    });
   } else {
    statusbar.first().css('visibility', 'hidden');
   }
   if (self.resizeType === 2) {
    _drag({
     moveEl : container,
     clickEl : statusbar.last(),
     moveFn : function(x, y, width, height, diffX, diffY) {
      width += diffX;
      height += diffY;
      newResize(width, height);
     }
    });
   } else {
    statusbar.last().css('visibility', 'hidden');
   }
  }
  return self;
 },
 remove : function() {
  var self = this;
  if (!self.isCreated) {
   return self;
  }
  self.beforeRemove();
  self.srcElement.data('kindeditor', '');
  if (self.menu) {
   self.hideMenu();
  }
  _each(self.dialogs, function() {
   self.hideDialog();
  });
  K(document).unbind('mousedown', self._docMousedownFn);
  self.toolbar.remove();
  self.edit.remove();
  self.statusbar.last().unbind();
  self.statusbar.unbind();
  self.container.remove();
  self.container = self.toolbar = self.edit = self.menu = null;
  self.dialogs = [];
  self.isCreated = false;
  return self;
 },
 resize : function(width, height) {
  var self = this;
  if (width !== null) {
   if (_removeUnit(width) > self.minWidth) {
    self.container.css('width', _addUnit(width));
   }
  }
  if (height !== null && self.toolbar.div && self.statusbar) {
   height = _removeUnit(height) - self.toolbar.div.height() - self.statusbar.height();
   if (height > 0 && _removeUnit(height) > self.minHeight) {
    self.edit.setHeight(height);
   }
  }
  return self;
 },
 select : function() {
  this.isCreated && this.cmd.select();
  return this;
 },
 html : function(val) {
  var self = this;
  if (val === undefined) {
   return self.isCreated ? self.edit.html() : _elementVal(self.srcElement);
  }
  self.isCreated ? self.edit.html(val) : _elementVal(self.srcElement, val);
  return self;
 },
 fullHtml : function() {
  return this.isCreated ? this.edit.html(undefined, true) : '';
 },
 text : function(val) {
  var self = this;
  if (val === undefined) {
   return _trim(self.html().replace(/<(?!img|embed).*?>/ig, '').replace(/&nbsp;/ig, ' '));
  } else {
   return self.html(_escape(val));
  }
 },
 isEmpty : function() {
  return _trim(this.text().replace(/\r\n|\n|\r/, '')) === '';
 },
 isDirty : function() {
  return _trim(this.initContent.replace(/\r\n|\n|\r|t/g, '')) !== _trim(this.html().replace(/\r\n|\n|\r|t/g, ''));
 },
 selectedHtml : function() {
  return this.isCreated ? this.cmd.range.html() : '';
 },
 count : function(mode) {
  var self = this;
  mode = (mode || 'html').toLowerCase();
  if (mode === 'html') {
   return _removeBookmarkTag(_removeTempTag(self.html())).length;
  }
  if (mode === 'text') {
   return self.text().replace(/<(?:img|embed).*?>/ig, 'K').replace(/\r\n|\n|\r/g, '').length;
  }
  return 0;
 },
 exec : function(key) {
  key = key.toLowerCase();
  var self = this, cmd = self.cmd,
   changeFlag = _inArray(key, 'selectall,copy,paste,print'.split(',')) < 0;
  if (changeFlag) {
   self.addBookmark(false);
  }
  cmd[key].apply(cmd, _toArray(arguments, 1));
  if (changeFlag) {
   self.updateState();
   self.addBookmark(false);
   if (self.options.afterChange) {
    self.options.afterChange.call(self);
   }
  }
  return self;
 },
 insertHtml : function(val, quickMode) {
  if (!this.isCreated) {
   return this;
  }
  val = this.beforeSetHtml(val);
  this.exec('inserthtml', val, quickMode);
  return this;
 },
 appendHtml : function(val) {
  this.html(this.html() + val);
  if (this.isCreated) {
   var cmd = this.cmd;
   cmd.range.selectNodeContents(cmd.doc.body).collapse(false);
   cmd.select();
  }
  return this;
 },
 sync : function() {
  _elementVal(this.srcElement, this.html());
  return this;
 },
 focus : function() {
  this.isCreated ? this.edit.focus() : this.srcElement[0].focus();
  return this;
 },
 blur : function() {
  this.isCreated ? this.edit.blur() : this.srcElement[0].blur();
  return this;
 },
 addBookmark : function(checkSize) {
  checkSize = _undef(checkSize, true);
  var self = this, edit = self.edit,
   body = edit.doc.body,
   html = _removeTempTag(body.innerHTML), bookmark;
  if (checkSize && self._undoStack.length > 0) {
   var prev = self._undoStack[self._undoStack.length - 1];
   if (Math.abs(html.length - _removeBookmarkTag(prev.html).length) < self.minChangeSize) {
    return self;
   }
  }
  if (edit.designMode && !self._firstAddBookmark) {
   var range = self.cmd.range;
   bookmark = range.createBookmark(true);
   bookmark.html = _removeTempTag(body.innerHTML);
   range.moveToBookmark(bookmark);
  } else {
   bookmark = {
    html : html
   };
  }
  self._firstAddBookmark = false;
  _addBookmarkToStack(self._undoStack, bookmark);
  return self;
 },
 undo : function() {
  return _undoToRedo.call(this, this._undoStack, this._redoStack);
 },
 redo : function() {
  return _undoToRedo.call(this, this._redoStack, this._undoStack);
 },
 fullscreen : function(bool) {
  this.fullscreenMode = (bool === undefined ? !this.fullscreenMode : bool);
  return this.remove().create();
 },
 readonly : function(isReadonly) {
  isReadonly = _undef(isReadonly, true);
  var self = this, edit = self.edit, doc = edit.doc;
  if (self.designMode) {
   self.toolbar.disableAll(isReadonly, []);
  } else {
   _each(self.noDisableItems, function() {
    self.toolbar[isReadonly ? 'disable' : 'enable'](this);
   });
  }
  if (_IE) {
   doc.body.contentEditable = !isReadonly;
  } else {
   doc.designMode = isReadonly ? 'off' : 'on';
  }
  edit.textarea[0].disabled = isReadonly;
 },
 createMenu : function(options) {
  var self = this,
   name = options.name,
   knode = self.toolbar.get(name),
   pos = knode.pos();
  options.x = pos.x;
  options.y = pos.y + knode.height();
  options.z = self.options.zIndex;
  options.shadowMode = _undef(options.shadowMode, self.shadowMode);
  if (options.selectedColor !== undefined) {
   options.cls = 'ke-colorpicker-' + self.themeType;
   options.noColor = self.lang('noColor');
   self.menu = _colorpicker(options);
  } else {
   options.cls = 'ke-menu-' + self.themeType;
   options.centerLineMode = false;
   self.menu = _menu(options);
  }
  return self.menu;
 },
 hideMenu : function() {
  this.menu.remove();
  this.menu = null;
  return this;
 },
 hideContextmenu : function() {
  this.contextmenu.remove();
  this.contextmenu = null;
  return this;
 },
 createDialog : function(options) {
  var self = this, name = options.name;
  options.z = self.options.zIndex;
  options.shadowMode = _undef(options.shadowMode, self.shadowMode);
  options.closeBtn = _undef(options.closeBtn, {
   name : self.lang('close'),
   click : function(e) {
    self.hideDialog();
    if (_IE && self.cmd) {
     self.cmd.select();
    }
   }
  });
  options.noBtn = _undef(options.noBtn, {
   name : self.lang(options.yesBtn ? 'no' : 'close'),
   click : function(e) {
    self.hideDialog();
    if (_IE && self.cmd) {
     self.cmd.select();
    }
   }
  });
  if (self.dialogAlignType != 'page') {
   options.alignEl = self.container;
  }
  options.cls = 'ke-dialog-' + self.themeType;
  if (self.dialogs.length > 0) {
   var firstDialog = self.dialogs[0],
    parentDialog = self.dialogs[self.dialogs.length - 1];
   firstDialog.setMaskIndex(parentDialog.z + 2);
   options.z = parentDialog.z + 3;
   options.showMask = false;
  }
  var dialog = _dialog(options);
  self.dialogs.push(dialog);
  return dialog;
 },
 hideDialog : function() {
  var self = this;
  if (self.dialogs.length > 0) {
   self.dialogs.pop().remove();
  }
  if (self.dialogs.length > 0) {
   var firstDialog = self.dialogs[0],
    parentDialog = self.dialogs[self.dialogs.length - 1];
   firstDialog.setMaskIndex(parentDialog.z - 1);
  }
  return self;
 },
 errorDialog : function(html) {
  var self = this;
  var dialog = self.createDialog({
   width : 750,
   title : self.lang('uploadError'),
   body : '<div style="padding:10px 20px;"><iframe frameborder="0" style="width:708px;height:400px;"></iframe></div>'
  });
  var iframe = K('iframe', dialog.div), doc = K.iframeDoc(iframe);
  doc.open();
  doc.write(html);
  doc.close();
  K(doc.body).css('background-color', '#FFF');
  iframe[0].contentWindow.focus();
  return self;
 }
};
function _editor(options) {
 return new KEditor(options);
}
_instances = [];
function _create(expr, options) {
 options = options || {};
 options.basePath = _undef(options.basePath, K.basePath);
 options.themesPath = _undef(options.themesPath, options.basePath + 'themes/');
 options.langPath = _undef(options.langPath, options.basePath + 'lang/');
 options.pluginsPath = _undef(options.pluginsPath, options.basePath + 'plugins/');
 if (_undef(options.loadStyleMode, K.options.loadStyleMode)) {
  var themeType = _undef(options.themeType, K.options.themeType);
  _loadStyle(options.themesPath + 'default/default.css');
  _loadStyle(options.themesPath + themeType + '/' + themeType + '.css');
 }
 function create(editor) {
  _each(_plugins, function(name, fn) {
   fn.call(editor, KindEditor);
  });
  return editor.create();
 }
 var knode = K(expr);
 if (!knode || knode.length === 0) {
  return;
 }
 if (knode.length > 1) {
  knode.each(function() {
   _create(this, options);
  });
  return _instances[0];
 }
 options.srcElement = knode[0];
 var editor = new KEditor(options);
 _instances.push(editor);
 if (_language[editor.langType]) {
  return create(editor);
 }
 _loadScript(editor.langPath + editor.langType + '.js?ver=' + encodeURIComponent(K.DEBUG ? _TIME : _VERSION), function() {
  create(editor);
 });
 return editor;
}
function _eachEditor(expr, fn) {
 K(expr).each(function(i, el) {
  K.each(_instances, function(j, editor) {
   if (editor && editor.srcElement[0] == el) {
    fn.call(editor, j, editor);
    return false;
   }
  });
 });
}
K.remove = function(expr) {
 _eachEditor(expr, function(i) {
  this.remove();
  _instances.splice(i, 1);
 });
};
K.sync = function(expr) {
 _eachEditor(expr, function() {
  this.sync();
 });
};
if (_IE && _V < 7) {
 _nativeCommand(document, 'BackgroundImageCache', true);
}
K.EditorClass = KEditor;
K.editor = _editor;
K.create = _create;
K.instances = _instances;
K.plugin = _plugin;
K.lang = _lang;
_plugin('core', function(K) {
 var self = this,
  shortcutKeys = {
   undo : 'Z', redo : 'Y', bold : 'B', italic : 'I', underline : 'U', print : 'P', selectall : 'A'
  };
 self.afterSetHtml(function() {
  if (self.options.afterChange) {
   self.options.afterChange.call(self);
  }
 });
 self.afterCreate(function() {
  if (self.syncType != 'form') {
   return;
  }
  var el = K(self.srcElement), hasForm = false;
  while ((el = el.parent())) {
   if (el.name == 'form') {
    hasForm = true;
    break;
   }
  }
  if (hasForm) {
   el.bind('submit', function(e) {
    self.sync();
    K(window).bind('unload', function() {
     self.edit.textarea.remove();
    });
   });
   var resetBtn = K('[type="reset"]', el);
   resetBtn.click(function() {
    self.html(self.initContent);
    self.cmd.selection();
   });
   self.beforeRemove(function() {
    el.unbind();
    resetBtn.unbind();
   });
  }
 });
 self.clickToolbar('source', function() {
  if (self.edit.designMode) {
   self.toolbar.disableAll(true);
   self.edit.design(false);
   self.toolbar.select('source');
  } else {
   self.toolbar.disableAll(false);
   self.edit.design(true);
   self.toolbar.unselect('source');
  }
  self.designMode = self.edit.designMode;
 });
 self.afterCreate(function() {
  if (!self.designMode) {
   self.toolbar.disableAll(true).select('source');
  }
 });
 self.clickToolbar('fullscreen', function() {
  self.fullscreen();
 });
 if (self.fullscreenShortcut) {
  var loaded = false;
  self.afterCreate(function() {
   K(self.edit.doc, self.edit.textarea).keyup(function(e) {
    if (e.which == 27) {
     setTimeout(function() {
      self.fullscreen();
     }, 0);
    }
   });
   if (loaded) {
    if (_IE && !self.designMode) {
     return;
    }
    self.focus();
   }
   if (!loaded) {
    loaded = true;
   }
  });
 }
 _each('undo,redo'.split(','), function(i, name) {
  if (shortcutKeys[name]) {
   self.afterCreate(function() {
    _ctrl(this.edit.doc, shortcutKeys[name], function() {
     self.clickToolbar(name);
    });
   });
  }
  self.clickToolbar(name, function() {
   self[name]();
  });
 });
 self.clickToolbar('formatblock', function() {
  var blocks = self.lang('formatblock.formatBlock'),
   heights = {
    h1 : 28,
    h2 : 24,
    h3 : 18,
    H4 : 14,
    p : 12
   },
   curVal = self.cmd.val('formatblock'),
   menu = self.createMenu({
    name : 'formatblock',
    width : self.langType == 'en' ? 200 : 150
   });
  _each(blocks, function(key, val) {
   var style = 'font-size:' + heights[key] + 'px;';
   if (key.charAt(0) === 'h') {
    style += 'font-weight:bold;';
   }
   menu.addItem({
    title : '<span style="' + style + '" unselectable="on">' + val + '</span>',
    height : heights[key] + 12,
    checked : (curVal === key || curVal === val),
    click : function() {
     self.select().exec('formatblock', '<' + key + '>').hideMenu();
    }
   });
  });
 });
 self.clickToolbar('fontname', function() {
  var curVal = self.cmd.val('fontname'),
   menu = self.createMenu({
    name : 'fontname',
    width : 150
   });
  _each(self.lang('fontname.fontName'), function(key, val) {
   menu.addItem({
    title : '<span style="font-family: ' + key + ';" unselectable="on">' + val + '</span>',
    checked : (curVal === key.toLowerCase() || curVal === val.toLowerCase()),
    click : function() {
     self.exec('fontname', key).hideMenu();
    }
   });
  });
 });
 self.clickToolbar('fontsize', function() {
  var curVal = self.cmd.val('fontsize'),
   menu = self.createMenu({
    name : 'fontsize',
    width : 150
   });
  _each(self.fontSizeTable, function(i, val) {
   menu.addItem({
    title : '<span style="font-size:' + val + ';" unselectable="on">' + val + '</span>',
    height : _removeUnit(val) + 12,
    checked : curVal === val,
    click : function() {
     self.exec('fontsize', val).hideMenu();
    }
   });
  });
 });
 _each('forecolor,hilitecolor'.split(','), function(i, name) {
  self.clickToolbar(name, function() {
   self.createMenu({
    name : name,
    selectedColor : self.cmd.val(name) || 'default',
    colors : self.colorTable,
    click : function(color) {
     self.exec(name, color).hideMenu();
    }
   });
  });
 });
 _each(('cut,copy,paste').split(','), function(i, name) {
  self.clickToolbar(name, function() {
   self.focus();
   try {
    self.exec(name, null);
   } catch(e) {
    alert(self.lang(name + 'Error'));
   }
  });
 });
 self.clickToolbar('about', function() {
  var html = '<div style="margin:20px;">' +
   '<div>KindEditor ' + _VERSION + '</div>' +
   '<div>Copyright &copy; <a href="http://www.kindsoft.net/" target="_blank">kindsoft.net</a> All rights reserved.</div>' +
   '</div>';
  self.createDialog({
   name : 'about',
   width : 300,
   title : self.lang('about'),
   body : html
  });
 });
 self.plugin.getSelectedLink = function() {
  return self.cmd.commonAncestor('a');
 };
 self.plugin.getSelectedImage = function() {
  return _getImageFromRange(self.edit.cmd.range, function(img) {
   return !/^ke-\w+$/i.test(img[0].className);
  });
 };
 self.plugin.getSelectedFlash = function() {
  return _getImageFromRange(self.edit.cmd.range, function(img) {
   return img[0].className == 'ke-flash';
  });
 };
 self.plugin.getSelectedMedia = function() {
  return _getImageFromRange(self.edit.cmd.range, function(img) {
   return img[0].className == 'ke-media' || img[0].className == 'ke-rm';
  });
 };
 self.plugin.getSelectedAnchor = function() {
  return _getImageFromRange(self.edit.cmd.range, function(img) {
   return img[0].className == 'ke-anchor';
  });
 };
 _each('link,image,flash,media,anchor'.split(','), function(i, name) {
  var uName = name.charAt(0).toUpperCase() + name.substr(1);
  _each('edit,delete'.split(','), function(j, val) {
   self.addContextmenu({
    title : self.lang(val + uName),
    click : function() {
     self.loadPlugin(name, function() {
      self.plugin[name][val]();
      self.hideMenu();
     });
    },
    cond : self.plugin['getSelected' + uName],
    width : 150,
    iconClass : val == 'edit' ? 'ke-icon-' + name : undefined
   });
  });
  self.addContextmenu({ title : '-' });
 });
 self.plugin.getSelectedTable = function() {
  return self.cmd.commonAncestor('table');
 };
 self.plugin.getSelectedRow = function() {
  return self.cmd.commonAncestor('tr');
 };
 self.plugin.getSelectedCell = function() {
  return self.cmd.commonAncestor('td');
 };
 _each(('prop,cellprop,colinsertleft,colinsertright,rowinsertabove,rowinsertbelow,rowmerge,colmerge,' +
 'rowsplit,colsplit,coldelete,rowdelete,insert,delete').split(','), function(i, val) {
  var cond = _inArray(val, ['prop', 'delete']) < 0 ? self.plugin.getSelectedCell : self.plugin.getSelectedTable;
  self.addContextmenu({
   title : self.lang('table' + val),
   click : function() {
    self.loadPlugin('table', function() {
     self.plugin.table[val]();
     self.hideMenu();
    });
   },
   cond : cond,
   width : 170,
   iconClass : 'ke-icon-table' + val
  });
 });
 self.addContextmenu({ title : '-' });
 _each(('selectall,justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,' +
  'insertunorderedlist,indent,outdent,subscript,superscript,hr,print,' +
  'bold,italic,underline,strikethrough,removeformat,unlink').split(','), function(i, name) {
  if (shortcutKeys[name]) {
   self.afterCreate(function() {
    _ctrl(this.edit.doc, shortcutKeys[name], function() {
     self.cmd.selection();
     self.clickToolbar(name);
    });
   });
  }
  self.clickToolbar(name, function() {
   self.focus().exec(name, null);
  });
 });
 self.afterCreate(function() {
  var doc = self.edit.doc, cmd, bookmark, div,
   cls = '__kindeditor_paste__', pasting = false;
  function movePastedData() {
   cmd.range.moveToBookmark(bookmark);
   cmd.select();
   if (_WEBKIT) {
    K('div.' + cls, div).each(function() {
     K(this).after('<br />').remove(true);
    });
    K('span.Apple-style-span', div).remove(true);
    K('span.Apple-tab-span', div).remove(true);
    K('span[style]', div).each(function() {
     if (K(this).css('white-space') == 'nowrap') {
      K(this).remove(true);
     }
    });
    K('meta', div).remove();
   }
   var html = div[0].innerHTML;
   div.remove();
   if (html === '') {
    return;
   }
   if (_WEBKIT) {
    html = html.replace(/(<br>)\1/ig, '$1');
   }
   if (self.pasteType === 2) {
    html = html.replace(/(<(?:p|p\s[^>]*)>) *(<\/p>)/ig, '');
    if (/schemas-microsoft-com|worddocument|mso-\w+/i.test(html)) {
     html = _clearMsWord(html, self.filterMode ? self.htmlTags : K.options.htmlTags);
    } else {
     html = _formatHtml(html, self.filterMode ? self.htmlTags : null);
     html = self.beforeSetHtml(html);
    }
   }
   if (self.pasteType === 1) {
    html = html.replace(/&nbsp;/ig, ' ');
    html = html.replace(/\n\s*\n/g, '\n');
    html = html.replace(/<br[^>]*>/ig, '\n');
    html = html.replace(/<\/p><p[^>]*>/ig, '\n');
    html = html.replace(/<[^>]+>/g, '');
    html = html.replace(/ {2}/g, ' &nbsp;');
    if (self.newlineTag == 'p') {
     if (/\n/.test(html)) {
      html = html.replace(/^/, '<p>').replace(/$/, '<br /></p>').replace(/\n/g, '<br /></p><p>');
     }
    } else {
     html = html.replace(/\n/g, '<br />$&');
    }
   }
   self.insertHtml(html, true);
  }
  K(doc.body).bind('paste', function(e){
   if (self.pasteType === 0) {
    e.stop();
    return;
   }
   if (pasting) {
    return;
   }
   pasting = true;
   K('div.' + cls, doc).remove();
   cmd = self.cmd.selection();
   bookmark = cmd.range.createBookmark();
   div = K('<div class="' + cls + '"></div>', doc).css({
    position : 'absolute',
    width : '1px',
    height : '1px',
    overflow : 'hidden',
    left : '-1981px',
    top : K(bookmark.start).pos().y + 'px',
    'white-space' : 'nowrap'
   });
   K(doc.body).append(div);
   if (_IE) {
    var rng = cmd.range.get(true);
    rng.moveToElementText(div[0]);
    rng.select();
    rng.execCommand('paste');
    e.preventDefault();
   } else {
    cmd.range.selectNodeContents(div[0]);
    cmd.select();
   }
   setTimeout(function() {
    movePastedData();
    pasting = false;
   }, 0);
  });
 });
 self.beforeGetHtml(function(html) {
  if (_IE && _V <= 8) {
   html = html.replace(/<div\s+[^>]*data-ke-input-tag="([^"]*)"[^>]*>([\s\S]*?)<\/div>/ig, function(full, tag) {
    return unescape(tag);
   });
  }
  return html.replace(/(<(?:noscript|noscript\s[^>]*)>)([\s\S]*?)(<\/noscript>)/ig, function($0, $1, $2, $3) {
   return $1 + _unescape($2).replace(/\s+/g, ' ') + $3;
  })
  .replace(/<img[^>]*class="?ke-(flash|rm|media)"?[^>]*>/ig, function(full) {
   var imgAttrs = _getAttrList(full),
    styles = _getCssList(imgAttrs.style || ''),
    attrs = _mediaAttrs(imgAttrs['data-ke-tag']);
   attrs.width = _undef(imgAttrs.width, _removeUnit(_undef(styles.width, '')));
   attrs.height = _undef(imgAttrs.height, _removeUnit(_undef(styles.height, '')));
   return _mediaEmbed(attrs);
  })
  .replace(/<img[^>]*class="?ke-anchor"?[^>]*>/ig, function(full) {
   var imgAttrs = _getAttrList(full);
   return '<a name="' + unescape(imgAttrs['data-ke-name']) + '"></a>';
  })
  .replace(/<div\s+[^>]*data-ke-script-attr="([^"]*)"[^>]*>([\s\S]*?)<\/div>/ig, function(full, attr, code) {
   return '<script' + unescape(attr) + '>' + unescape(code) + '</script>';
  })
  .replace(/<div\s+[^>]*data-ke-noscript-attr="([^"]*)"[^>]*>([\s\S]*?)<\/div>/ig, function(full, attr, code) {
   return '<noscript' + unescape(attr) + '>' + unescape(code) + '</noscript>';
  })
  .replace(/(<[^>]*)data-ke-src="([^"]*)"([^>]*>)/ig, function(full, start, src, end) {
   full = full.replace(/(\s+(?:href|src)=")[^"]*(")/i, function($0, $1, $2) {
    return $1 + _unescape(src) + $2;
   });
   full = full.replace(/\s+data-ke-src="[^"]*"/i, '');
   return full;
  })
  .replace(/(<[^>]+\s)data-ke-(on\w+="[^"]*"[^>]*>)/ig, function(full, start, end) {
   return start + end;
  });
 });
 self.beforeSetHtml(function(html) {
  if (_IE && _V <= 8) {
   html = html.replace(/<input[^>]*>|<(select|button)[^>]*>[\s\S]*?<\/\1>/ig, function(full) {
    var attrs = _getAttrList(full);
    var styles = _getCssList(attrs.style || '');
    if (styles.display == 'none') {
     return '<div class="ke-display-none" data-ke-input-tag="' + escape(full) + '"></div>';
    }
    return full;
   });
  }
  return html.replace(/<embed[^>]*type="([^"]+)"[^>]*>(?:<\/embed>)?/ig, function(full) {
   var attrs = _getAttrList(full);
   attrs.src = _undef(attrs.src, '');
   attrs.width = _undef(attrs.width, 0);
   attrs.height = _undef(attrs.height, 0);
   return _mediaImg(self.themesPath + 'common/blank.gif', attrs);
  })
  .replace(/<a[^>]*name="([^"]+)"[^>]*>(?:<\/a>)?/ig, function(full) {
   var attrs = _getAttrList(full);
   if (attrs.href !== undefined) {
    return full;
   }
   return '<img class="ke-anchor" src="' + self.themesPath + 'common/anchor.gif" data-ke-name="' + escape(attrs.name) + '" />';
  })
  .replace(/<script([^>]*)>([\s\S]*?)<\/script>/ig, function(full, attr, code) {
   return '<div class="ke-script" data-ke-script-attr="' + escape(attr) + '">' + escape(code) + '</div>';
  })
  .replace(/<noscript([^>]*)>([\s\S]*?)<\/noscript>/ig, function(full, attr, code) {
   return '<div class="ke-noscript" data-ke-noscript-attr="' + escape(attr) + '">' + escape(code) + '</div>';
  })
  .replace(/(<[^>]*)(href|src)="([^"]*)"([^>]*>)/ig, function(full, start, key, src, end) {
   if (full.match(/\sdata-ke-src="[^"]*"/i)) {
    return full;
   }
   full = start + key + '="' + src + '"' + ' data-ke-src="' + _escape(src) + '"' + end;
   return full;
  })
  .replace(/(<[^>]+\s)(on\w+="[^"]*"[^>]*>)/ig, function(full, start, end) {
   return start + 'data-ke-' + end;
  })
  .replace(/<table[^>]*\s+border="0"[^>]*>/ig, function(full) {
   if (full.indexOf('ke-zeroborder') >= 0) {
    return full;
   }
   return _addClassToTag(full, 'ke-zeroborder');
  });
 });
});
})(window);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值