tchao 3 năm trước cách đây
mục cha
commit
fcb391c584
100 tập tin đã thay đổi với 18772 bổ sung0 xóa
  1. 283 0
      web/js/ueditor2/CHANGELOG.TXT
  2. 257 0
      web/js/ueditor2/_src/commands.js
  3. 1068 0
      web/js/ueditor2/_src/core/Editor.js
  4. 96 0
      web/js/ueditor2/_src/core/EventBase.js
  5. 1228 0
      web/js/ueditor2/_src/core/Range.js
  6. 340 0
      web/js/ueditor2/_src/core/Selection.js
  7. 132 0
      web/js/ueditor2/_src/core/ajax.js
  8. 167 0
      web/js/ueditor2/_src/core/browser.js
  9. 1285 0
      web/js/ueditor2/_src/core/domUtils.js
  10. 186 0
      web/js/ueditor2/_src/core/dtd.js
  11. 167 0
      web/js/ueditor2/_src/core/filterword.js
  12. 613 0
      web/js/ueditor2/_src/core/utils.js
  13. 151 0
      web/js/ueditor2/_src/customEvent.js
  14. 19 0
      web/js/ueditor2/_src/editor.js
  15. 42 0
      web/js/ueditor2/_src/extend/ExtendConf.js
  16. 63 0
      web/js/ueditor2/_src/extend/plugins/cascadequery.js
  17. 43 0
      web/js/ueditor2/_src/extend/plugins/choosetemplate.js
  18. 32 0
      web/js/ueditor2/_src/extend/plugins/customdialog.js
  19. 98 0
      web/js/ueditor2/_src/extend/plugins/customquery.js
  20. 53 0
      web/js/ueditor2/_src/extend/plugins/datecalculate.js
  21. 54 0
      web/js/ueditor2/_src/extend/plugins/daterangevalidate.js
  22. 19 0
      web/js/ueditor2/_src/extend/plugins/exportexceldialog.js
  23. 17 0
      web/js/ueditor2/_src/extend/plugins/exportform.js
  24. 11 0
      web/js/ueditor2/_src/extend/plugins/flowchart.js
  25. 19 0
      web/js/ueditor2/_src/extend/plugins/importexceldialog.js
  26. 16 0
      web/js/ueditor2/_src/extend/plugins/importform.js
  27. 1322 0
      web/js/ueditor2/_src/extend/plugins/input.js
  28. 29 0
      web/js/ueditor2/_src/extend/plugins/international.js
  29. 39 0
      web/js/ueditor2/_src/extend/plugins/mathfunction.js
  30. 26 0
      web/js/ueditor2/_src/extend/plugins/numbervalidate.js
  31. 42 0
      web/js/ueditor2/_src/extend/plugins/opinion.js
  32. 24 0
      web/js/ueditor2/_src/extend/plugins/pasteinput.js
  33. 16 0
      web/js/ueditor2/_src/extend/plugins/serialnum.js
  34. 79 0
      web/js/ueditor2/_src/extend/plugins/setreadonly.js
  35. 55 0
      web/js/ueditor2/_src/extend/plugins/subtable.js
  36. 11 0
      web/js/ueditor2/_src/extend/plugins/taskopinion.js
  37. 20 0
      web/js/ueditor2/_src/extend/plugins/wordtemplate.js
  38. 47 0
      web/js/ueditor2/_src/plugins/anchor.js
  39. 131 0
      web/js/ueditor2/_src/plugins/autofloat.js
  40. 107 0
      web/js/ueditor2/_src/plugins/autoheight.js
  41. 104 0
      web/js/ueditor2/_src/plugins/autolink.js
  42. 24 0
      web/js/ueditor2/_src/plugins/autosubmit.js
  43. 252 0
      web/js/ueditor2/_src/plugins/autotypeset.js
  44. 33 0
      web/js/ueditor2/_src/plugins/background.js
  45. 68 0
      web/js/ueditor2/_src/plugins/basestyle.js
  46. 154 0
      web/js/ueditor2/_src/plugins/blockquote.js
  47. 95 0
      web/js/ueditor2/_src/plugins/catchremoteimage.js
  48. 28 0
      web/js/ueditor2/_src/plugins/cleardoc.js
  49. 367 0
      web/js/ueditor2/_src/plugins/contextmenu.js
  50. 39 0
      web/js/ueditor2/_src/plugins/convertcase.js
  51. 134 0
      web/js/ueditor2/_src/plugins/customstyle.js
  52. 103 0
      web/js/ueditor2/_src/plugins/directionality.js
  53. 49 0
      web/js/ueditor2/_src/plugins/elementpath.js
  54. 192 0
      web/js/ueditor2/_src/plugins/enterkey.js
  55. 18 0
      web/js/ueditor2/_src/plugins/fiximgclick.js
  56. 174 0
      web/js/ueditor2/_src/plugins/font.js
  57. 129 0
      web/js/ueditor2/_src/plugins/formatmatch.js
  58. 193 0
      web/js/ueditor2/_src/plugins/highlightcode.js
  59. 46 0
      web/js/ueditor2/_src/plugins/horizontal.js
  60. 19 0
      web/js/ueditor2/_src/plugins/iframe.js
  61. 188 0
      web/js/ueditor2/_src/plugins/image.js
  62. 22 0
      web/js/ueditor2/_src/plugins/indent.js
  63. 156 0
      web/js/ueditor2/_src/plugins/inserthtml.js
  64. 36 0
      web/js/ueditor2/_src/plugins/insertparagraph.js
  65. 93 0
      web/js/ueditor2/_src/plugins/justify.js
  66. 166 0
      web/js/ueditor2/_src/plugins/keystrokes.js
  67. 31 0
      web/js/ueditor2/_src/plugins/lineheight.js
  68. 153 0
      web/js/ueditor2/_src/plugins/link.js
  69. 910 0
      web/js/ueditor2/_src/plugins/list.js
  70. 75 0
      web/js/ueditor2/_src/plugins/music.js
  71. 128 0
      web/js/ueditor2/_src/plugins/pagebreak.js
  72. 150 0
      web/js/ueditor2/_src/plugins/paragraph.js
  73. 311 0
      web/js/ueditor2/_src/plugins/paste.js
  74. 25 0
      web/js/ueditor2/_src/plugins/preview.js
  75. 17 0
      web/js/ueditor2/_src/plugins/print.js
  76. 176 0
      web/js/ueditor2/_src/plugins/removeformat.js
  77. 40 0
      web/js/ueditor2/_src/plugins/rowspacing.js
  78. 10 0
      web/js/ueditor2/_src/plugins/scrawl.js
  79. 144 0
      web/js/ueditor2/_src/plugins/searchreplace.js
  80. 75 0
      web/js/ueditor2/_src/plugins/selectall.js
  81. 805 0
      web/js/ueditor2/_src/plugins/serialize.js
  82. 14 0
      web/js/ueditor2/_src/plugins/signset.js
  83. 68 0
      web/js/ueditor2/_src/plugins/snapscreen.js
  84. 352 0
      web/js/ueditor2/_src/plugins/source.js
  85. 3044 0
      web/js/ueditor2/_src/plugins/table.js
  86. 39 0
      web/js/ueditor2/_src/plugins/template.js
  87. 30 0
      web/js/ueditor2/_src/plugins/time.js
  88. 245 0
      web/js/ueditor2/_src/plugins/undo.js
  89. 77 0
      web/js/ueditor2/_src/plugins/video.js
  90. 49 0
      web/js/ueditor2/_src/plugins/webapp.js
  91. 26 0
      web/js/ueditor2/_src/plugins/wordcount.js
  92. 33 0
      web/js/ueditor2/_src/plugins/wordimage.js
  93. 85 0
      web/js/ueditor2/_src/ui/autotypesetbutton.js
  94. 46 0
      web/js/ueditor2/_src/ui/autotypesetpicker.js
  95. 46 0
      web/js/ueditor2/_src/ui/button.js
  96. 55 0
      web/js/ueditor2/_src/ui/cellalignpicker.js
  97. 60 0
      web/js/ueditor2/_src/ui/colorbutton.js
  98. 74 0
      web/js/ueditor2/_src/ui/colorpicker.js
  99. 90 0
      web/js/ueditor2/_src/ui/combox.js
  100. 0 0
      web/js/ueditor2/_src/ui/dialog.js

+ 283 - 0
web/js/ueditor2/CHANGELOG.TXT

@@ -0,0 +1,283 @@
+UEditor Change List
+
+Version 1.2.5
+新增功能
+  . table整体重构
+  . table支持插入表头和标题
+  . table支持拷贝
+  . table支持任意调整宽高
+  . table支持任意前插后插行列
+  . table键盘操作仿word用户体验
+  . 添加table平均分布行、列
+  . 添加table单元格对齐方式
+  . 添加table对齐方式
+  . 添加选中部分表格,点击backspace或delete删除功能
+  . 重写表格属性、单元格属性dialog
+  . 粘贴支持纯文本,源码,纯标签3个模式选择
+  . 添加计算字数的getContentLength接口
+  . 添加计算字数事件wordcount
+  . 图片上传支持参数动态绑定
+  . 重写了list功能,支持一,一),(一),1),(1),——等新的列表标签
+  . 调整了list中tab键的逻辑
+  . 添加了可以限制列表的层级
+  . 全屏快捷键 ALT+Z
+  . 添加了uparse.js展示页加载器
+
+优化修复
+  . 优化了插入代码功能
+  . ie下默认禁用源码模式下的代码高亮
+  . 截图功能支持非ie浏览器
+  . 修正了非ie下中文输入时回退不准确的问题
+  . 改进了键盘输入时做回退的操作
+
+Version 1.2.4
+新增功能
+   . 官网新增API文档
+   . CSS按照UI结构进行了模块化拆分
+   . 新增皮肤切换功能,并提供一套新皮肤(可通过配置项theme来设置)
+   . 新增编辑器容器拖动缩放功能,配置项为:scaleEnabled、minFrameWidth、minFrameHeight
+   . 新增音乐插件
+   . 增加了源码模式下,全屏按钮可以使用
+   . 添加了UE.getEditor工厂方法
+   . 添加了针对jquery配合使用的demo
+   . 添加了针对jqueryValidation配合使用的demo
+   . 添加了初始化编辑器宽高配置,配置为项:initialFrameWidth、initialFrameHeight
+
+优化修复
+   . 修复涂鸦路径在配置时,添加参数时请求报错
+   . 修复涂鸦opera下缩放不能使用
+   . 修复编辑器全屏功能失效问题
+   . codemirror版本升级到最新版
+   . 对opera/safari的支持进行了进一步的优化
+   . 优化了部分demo页的代码
+   . 修改原来的minFrameHeight为拖动时的最小高度
+
+Version 1.2.3
+新增功能
+   . 新增国际化支持
+   . 新增涂鸦功能
+   . 新增大小写功能
+   . 新增getAllHtml方法,可以将整个页面的内容打出来,可以在editor_config.js里通过配置allHtmlEnabled,来配置在提交时是否使用getAllHtml来得到内容
+   . 新增插入模板的功能
+   . 新增背景功能
+   . 新增UE.instants全局对象,下边挂接了所有实例化的编辑器对象
+   . Editor下新增ready方法,当编辑器ready后执行传入的fn,如果编辑器已经ready好了,就马上执行fn
+   . 新增topOffset配置参数,用于设置AutoFloat时工具栏距离顶部的高度
+   . 新增sourceEditorFirst配置参数,用于控制编辑器初始化时是否显示成源码模式,默认为否
+   . 新增在表格内实例化编辑器的demo
+   . 新增getDialog(dialogName)接口,可以获取dialog对象。
+
+优化修复
+   . chrome下会出现alt+tab切换时,导致选区位置不对
+   . focus方法添加参数可以指向到内容末尾
+   . 完全支持opera浏览器
+   . 修复了表格中实例化编辑器时工具栏浮动错位问题
+   . 优化了后台处理文件代码,文件夹按照日期自动生成
+
+
+Version 1.2.2
+1.编辑器不可编辑时,可以配置哪些功能可以使用,例如全屏
+2.table的边框为0时,采用虚线显示
+3.修复firefox下插入大量代码时,代码格式显示不正确的问题
+4.附件上传成功后显示初始文件名
+5.自定制下载优化
+6.当图片上传超时时,增加提示信息
+7.修复自动排版对H1不生效的问题
+8.修复插入超链接,超链接地址包含script标签,预览时会执行script语句的问题
+
+
+Version 1.2.1
+1.插入表情时,按住CTRL键可连续插入多个表情
+2.按住CTRL+Enter提交表单
+3.增加readonly属性在editor_config.js,编辑器实例上增加setEnabled,setDisabled方法,设置编辑区域是否可以编辑
+4.Editor上添加了getPlainTxt方法,得到编辑器的纯文本内容,但会保留段落格式
+5.修正了initialContent赋值失效的问题,赋值顺序以标签内容为先,如果没有再看initialContent内容。
+6.为insertHtml命令添加了过滤机制
+7.getContent将“ ”转成空格,连续2个空格则以“  ”表示
+8.当选区在一个超链接中,就可以在弹出层中直接修改这个超链接中的文本
+9.与后台交互的路径整体进行了调整
+10.超链接窗口可以修改超链接显示的文字
+11.增加插入百度应用的功能
+12.为每个plugin的在代码中添加了配置项的容错代码,若配置项不存在,不会报错
+13.提供后台的jsp版本
+14.重写了ui和和编辑器的交互层,dialog改为显示时创建,整体代码减少22k
+15.修正了代码高亮跟jquery冲突的问题
+16.改进了多个编辑器实例,使用一个name做为form提交,后台都可以取到
+17.添加是否删除空的inlineElement节点(包括嵌套的情况)的配置项:autoClearEmptyNode
+18.修正了chrome下粘贴文本带有white-space样式, 导致编辑器内容不能折行的问题
+19.在配置项中增加isShow设置初始化时是否显示编辑器,在编辑器实例上增加setShow,setHide方法设置编辑器的显示/隐藏
+20.修正在jquery中实例化编辑器时与UE自带的domready冲突的问题
+21.修正代码高亮中的行号与代码内容不能对齐的问题
+22.新增了图片上传对话框中可自定义配置默认Tab的功能
+23.修正.net源码包中gbk版本的乱码以及demo中使用了php路径的问题
+
+Version 1.2.0
+1.远程图片抓取
+3.源码模式下css进行了简写
+4.增加了baidu图片搜索功能,搜索图片然后直接插入到编辑器中
+5.重写了浮动工具栏,支持混乱模式下的工具栏滚动
+6.服务器图片在线管理
+7.word的本地图片取得寛高
+8.附件上传
+9.自动排版
+10.优化了状态反射的方式,改为编辑器获得焦点才会触发,失去焦点不在触发状态查询
+11.添加了上来就可以全屏的配置项哦去焦点之前的选区
+13.优化了查询状态反射的性能
+14.添加了contentchagne事件
+15.重写了autoheight插件,去掉setInterval的方式,并且长高时不在跳动
+16.插入视频,可以预览,并且界面加入了视屏搜索功能,并且可以插入视屏预览图到编辑器中
+17.单元格属性编辑
+18.ie下的截屏功能
+19.加强了table的dialog功能
+20.改进了autolink的效果,例如: dddhttp://www.baidu.com 回车,http://www.baidu.com也可以被匹配到了
+21.文件上传提供flash源码
+22.修改了行间距的展示方式
+23.段间距变为段前距和段后距
+24.提供了.net的事例代码
+25.首页提供了功能选择生成下载的新功能
+26.首页文档进行了改进
+27.分页符可以删除
+28.增强了表格的编辑功能
+
+Version 1.1.8
+1.避免了重复加载源码高亮的核心代码
+2.修复了word粘贴table过滤出错问题
+3.修复插入地图会出现style="undefined"的问题
+4.优化了list,多个相邻的属性一直的list会合并
+5.可以在列表中的一行里产生多行的效果(通过回车再回退操作),类似office的效果
+6.添加自定义样式功能
+7.修了在chrome下右键删除td里的图片会把整个td删除的问题
+8.改进了不同的页面调用一个editor,URL问题
+9.增加了颜色选择器的颜色
+10.改进了提供的后台程序的安全性
+11.代码高亮支持折行
+12.改进了源码编辑模式下的性能(ie下),并且支持自动换行
+13.修改了在destroy之后会在ie下报错的问题
+14.给初始化容器name值,那么在后台取值的键值就是name给定的值,方便多实例在一个form下提交
+15.支持插入script/style这样的标签
+16.修复了列表里插入浮动图片,图片不占位问题
+17.源码模式下,去掉了pre中的 
+18.完善了_example下的demo例子
+19.base64的图片被过滤掉了
+
+Version 1.1.7.3
+1.支持图片相对路径模式
+2.word粘贴首行缩进问题
+3.添加了图片边距
+4.提供了图片等比压缩时基准边选择配置的功能
+5.dialog在某些页面不显示问题
+6.添加了行内间距的调整
+7.在editor实例下添加了destroy方法
+8.全屏按钮位置不对的问题
+9.iframe.css支持相对和绝对路径
+10.修正了focus方法在ff下失效的问题
+11.提供了对FF3.6的支持
+12.添加了Shift+Enter软回车功能
+10.统一了颜色rgb转成#
+
+
+version 1.1.7.2
+1.去掉了iframe.css 改为在editor_config.js中配置,避免css文件找不到的问题
+2.给下拉菜单添加了默认的文字说明
+3.Ueditor.css去掉了对外部页面css的影响
+4.修正了ie9下,编辑器的高度不随着内容缩短的问题
+5.修正了粘贴有时会出现粘贴失败的情况
+6.修正了在ie下点击图片会出现js错误的问题
+7.修正了在ie下选全部替换,回退,再替换会出现替换失败的问题
+8.增加表情本地化模式,可在config中配置是否开启本地化
+9.flash的多图片上传
+10.支持了源码模式的下的代码高亮
+11.增加插入代码支持的语言,改进了插入代码的展示效果
+12.增加了字数统计
+13.增加了对图片的排版操作
+14.解决ie6和ie7下工具栏浮动时cpu占用过高的bug
+15.优化了文本模式粘贴的效果
+16.优化了word粘贴的效果
+17.在word粘贴本地图片时添加引导上传功能
+18.更好的ie9支持
+19.优化首行缩进效果
+20.使用script标签代替textarea标签作为编辑器容器,简化前后端转码的配置。
+21.优化了路径配置,修正了1.1.7.1中需要修改多处路径的问题
+22.增加了图片操作浮层的开关配置
+23.同时支持网络图片和本地图片的等比缩放
+24.优化了源码模式下的代码格式
+
+version 1.1.6.1
+1.去掉了iframe.css 改为在editor_config.js中配置,避免css文件找不到的问题
+2.给下拉菜单添加了默认的文字说明
+3.Ueditor.css去掉了对外部页面css的影响
+4.修正了ie9下,编辑器的高度不随着内容缩短的问题
+5.修正了粘贴有时会出现粘贴失败的情况
+6.修正了在ie下点击图片会出现js错误的问题
+7.修正了在ie下选全部替换,回退,再替换会出现替换失败的问题
+
+
+
+
+
+version 1.1.6
+1. 插入日期按钮现在使用tangram日历控件
+2. table可再编辑
+3. 粘贴excel表格的问题
+4. ff下最大化和切换源码出现光标不能跟着键盘改变和不能切出输入法的问题
+5. tab按键功能
+6. 支持多级列表
+7. 超链接可以在非ie下去除下划线
+8. 字体,字号,在editor-config.js中可配置
+
+
+
+version 1.1.5
+1.右键的策略,只显示选区内可操作的条目
+2.禁止elementpath还会留下边框问题
+3.字体改为了px
+4.插入分页符
+5.整合浮动toolbar为autofloat插件
+6.初始化的值会在第一次操作前清除,而且不在有延迟感
+7.配置项都放到了editor-config.js中
+8.修正了多实例的问题
+9.插入iframe功能
+10.粘贴过滤掉内容会有提示,没过滤任何内容不会出现提示
+11.修正代码高亮的显示效果
+12.list放弃原生改为手动实现,修正一系列原生的bug
+13.初始给个textarea会把内容取出作为初始值
+14.去掉了源码状态下冗余的table/td/pre的style属性
+15.fixed剪切出去会带start/end
+16.fixex源码模式下getContent内容不是新的
+17.table加入了设置背景颜色和边框颜色
+
+
+
+Version 1.1.4
+1.  锚点
+2.  首行缩进
+3.  行间距
+4.  右键菜单
+5.  插入代码
+6.  文件上传(php版本)
+7.  修复一些bug
+
+Version 1.1.3
+1.  修复chrome下粘贴的bug
+2.  自动转换office粘入的有序列表和无序列表
+3.  插入图片不再等比缩放,显示原始大小
+
+Version 1.1.2
+1.  修正IE9下autoHeight插件会一直长高的问题
+2.  增加对IE6下大写style属性的转换处理(现统一转换成小写)
+3.  格式刷
+4.  上下标互斥
+5.  form提交的支持
+6.  增加了focus属性,可以初始化时,设置是否编辑器获得焦点
+7.  增加了下滑线,删除线按钮,去掉了原来的下拉框
+8.  autolink支持,使非ie在输入链接时能自动加上a标签
+9.  google地图支持
+10. 修正了一些bug
+
+Version 1.1
+1.	修改了删除链接的机制,允许一次性删除多个超链接
+2.	改变了目录结构,方便部署(大大减少了开发代码过程中需要引入的js数量)
+3.	修正部分bug
+
+Version 1.0 (2011-7-8)
+1.	完成功能的开发

+ 257 - 0
web/js/ueditor2/_src/commands.js

@@ -0,0 +1,257 @@
+//本文件非编辑器核心文件,仅适用于生成对应的命令接口文档
+/**
+ * @file
+ * @name 编辑器命令接口
+ * @short Commands
+ * @desc
+ *
+ * UEditor中执行命令的统一调用格式为
+ * <code>editor.execCommand("cmdName"[,opt]);</code>
+ *
+ *
+ * 检测当前命令是否可用的方法是
+ * <code>editor.queryCommandState("cmdName");</code>
+ *
+ *
+ * 部分命令可以返回命令值,其格式为
+ * <code>editor.queryCommandValue("cmdName");</code>
+ */
+/**
+ * 插入锚点
+ * @name anchor
+ * @grammar editor.execCommand("anchor","name"); //锚点的名字
+ */
+/**
+ * 为当前选中文字添加粗体效果
+ * @name bold
+ * @grammar editor.execCommand("bold");
+ */
+/**
+ * 为当前选中文字添加斜体效果
+ * @name italic
+ * @grammar editor.execCommand("italic");
+ */
+/**
+ * 为当前选中文字添加下划线效果
+ * @name underline
+ * @grammar editor.execCommand("underline");
+ */
+
+
+/**
+ * 为当前选中文字添加删除线效果
+ * @name strikethrough
+ * @grammar editor.execCommand("strikethrough");
+ */
+/**
+ * 将当前选中文字转换成上标
+ * @name superscript
+ * @grammar editor.execCommand("superscript");
+ */
+/**
+ * 将当前选中文字转换成下标
+ * @name subscript
+ * @grammar editor.execCommand("subscript");
+ */
+/**
+ * 为当前选中文字添加颜色
+ * @name foreColor
+ * @grammar editor.execCommand("foreColor","#ffffff");
+ */
+/**
+ * 为当前选中文字添加背景颜色
+ * @name backColor
+ * @grammar editor.execCommand("backColor","#dddddd");
+ */
+/**
+ * 设置当前选中文字的字体
+ * @name fontFamily
+ * @grammar editor.execCommand("fontFamily","微软雅黑,Microsoft YaHei");
+ */
+/**
+ * 设置当前选中文字的字号
+ * @name fontSize
+ * @grammar editor.execCommand("fontSize","32px");
+ */
+/**
+ * 设置当前选区的段落格式,如p,h1,h2,h3,...
+ * @name paragraph
+ * @grammar editor.execCommand("paragraph","h1");
+ */
+/**
+ * 将当前选区变换成有序或者无序列表
+ * @name insert(Un)OrderedList
+ * @grammar editor.execCommand("insertOrderedList");
+ */
+/**
+ * 设置当前选区的行间距
+ * @name lineHeight
+ * @grammar editor.execCommand("lineHeight");
+ */
+/**
+ * 设置当前选区中的字体对齐方式
+ * @name justify
+ * @grammar editor.execCommand("justify",align);  //align可为Left,Right,Center,Justify
+ */
+/**
+ * 将当前选中文字中的字母转换成大写
+ * @name toUppercase
+ * @grammar editor.execCommand("toUppercase");
+ */
+/**
+ * 将当前选中文字中的字母转换成小写
+ * @name toLowercase
+ * @grammar editor.execCommand("toLowercase");
+ */
+/**
+ * 为当前选区所在的块级元素添加引用标记
+ * @name blockquote
+ * @grammar editor.execCommand("blockquote");
+ */
+/**
+ * 设置当前选区所在块级元素的文字输入方向
+ * @name directionality
+ * @grammar editor.execCommand("directionality",dir);  //dir可为LTR,RTL
+ */
+/**
+ * 清除当前选中文字上的所有样式或者指定样式
+ * @name removeFormat
+ * @grammar editor.execCommand("removeFormat")   //根据editor_config.js里的removeFormatTags,removeFormatAttributes两个属性作为规则
+ * @grammar editor.execCommand("removeFormat",tags,style);   //清除指定tags上的指定style
+ * @example
+ * editor.execCommand("removeFormat",'span,a','color,background-color')
+ */
+/**
+ * 切换纯文本粘贴模式
+ * @name pastePlain
+ * @grammar ue.execCommand("pastePlain");
+ */
+/**
+ * 开启格式刷功能
+ * @name formatMatch
+ * @grammar editor.execCommand("formatMatch");
+ */
+/**
+ * 清空文档
+ * @name clearDoc
+ * @grammar editor.execCommand("clearDoc");
+ */
+/**
+ * 删除当前选中文本
+ * @name delete
+ * @grammar editor.execCommand("delete");
+ */
+/**
+ * 全部选择
+ * @name selectAll
+ * @grammar editor.execCommand("selectAll");
+ */
+/**
+ * 撤销操作
+ * @name undo
+ * @grammar editor.execCommand("undo");
+ */
+/**
+ * 恢复操作
+ * @name redo
+ * @grammar editor.execCommand("redo");
+ */
+/**
+ * 对整个编辑文档进行自动排版
+ * @name autoTypeset
+ * @grammar editor.execCommand("autoTypeset");
+ */
+/**
+ * 在当前选区位置插入一段html代码,最基本功能。大部分其他插入命令都会调用此命令完成最后的插入
+ * @name insertHtml
+ * @grammar editor.execCommand("insertHtml","欢迎使用UEditor!")
+ */
+/**
+ * 在当前选区位置插入一个超链接
+ * @name link
+ * @grammar editor.execCommand("link",linkObj);
+ * @example
+ * editor.execCommand("link",{
+ *     href: "http://ueditor.baidu.com",         //超链地址,必选
+ *     data_ue_src: "http://ueditor.baidu.com",  //UE内部使用参数,与href保持一致即可,可选
+ *     target: "_self",                          //目标窗口,可选
+ *     textValue: "UEditor",                     //链接显示文本,可选
+ *     title: "百度开源富文本编辑器UEditor官网"     //标题,可选
+ * })
+ */
+/**
+ * 在当前选区位置插入一个图片
+ * @name insertImage
+ * @grammar editor.execCommand("insertImage",imageObj);
+ * @example
+ * editor.execCommand("insertImage",{
+ *     src: "http://ueditor.baidu.com/logo.jpg",          //图片链接地址,必选
+ *     data_ue_src: "http://ueditor.baidu.com/logo.jpg",  //UE内部使用参数,与src保持一致即可,可选
+ *     width: 300,                                        //图片显示宽度,可选
+ *     height: 400,                                       //图片显示高度,可选
+ *     border: 2,                                         //图片边框,可选
+ *     hspace: 5,                                         //图片左右边距,可选
+ *     vspace: 2,                                         //图片上下边距,可选
+ *     alt: 'UEditor-logo',                               //图片替换文字,可选
+ *     title: "百度开源富文本编辑器UEditor官网"             //图片标题,可选
+ * })
+ */
+/**
+ * 在当前选区位置插入一个视频
+ * @name insertVideo
+ * @grammar editor.execCommand("insertVideo",videoObj);
+ * @example
+ * editor.execCommand("insertVideo",{
+ *     url: "http://youku.com/id?id=1233122",   //视频地址,必选
+ *     width: 420,                              //视频宽度,可选
+ *     height: 280,                             //视频高度,可选
+ *     align: "none"                            //对齐方式,支持right,left,center,none ,可选
+ * })
+ */
+/**
+ * 在当前选区位置插入一个日期或者时间
+ * @name date|time
+ * @grammar editor.execCommand("date");
+ */
+/**
+ * 在当前选区位置插入一个分页符标记
+ * @name pageBreak
+ * @grammar editor.execCommand("pageBreak");
+ */
+/**
+ * 切换源码编辑模式和富文本编辑模式
+ * @name source
+ * @grammar editor.execCommand("source");
+ */
+/**
+ * IE下进入截屏模式
+ * @name snapScreen
+ * @grammar editor.execCommand("snapScreen");
+ */
+/**
+ * 插入表格
+ * @name insertTable
+ * @grammar editor.execCommand("insertTable",rows,cols);
+ */
+
+/**
+ * 查找替换
+ * @name searchreplace
+ * @grammar editor.execCommand("searchreplace",opt);
+ * @desc
+ * opt是个json对象,属性如下
+ * * ''all'' true表示查找整个文档,false表示从上次的位置开始查找,默认是false
+ * * ''casesensitive'' 大小写铭感,true是铭感,默认是false
+ * * ''dir'' 1表示从前往后查,-1表示从后往前
+ * * ''searchStr'' 查找的字符串
+ * * ''replaceStr'' 替换用的字符串
+ */
+
+
+
+
+
+
+
+
+

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1068 - 0
web/js/ueditor2/_src/core/Editor.js


+ 96 - 0
web/js/ueditor2/_src/core/EventBase.js

@@ -0,0 +1,96 @@
+/**
+ * @file
+ * @name UE.EventBase
+ * @short EventBase
+ * @import editor.js,core/utils.js
+ * @desc UE采用的事件基类,继承此类的对应类将获取addListener,removeListener,fireEvent方法。
+ * 在UE中,Editor以及所有ui实例都继承了该类,故可以在对应的ui对象以及editor对象上使用上述方法。
+ */
+var EventBase = UE.EventBase = function () {};
+
+EventBase.prototype = {
+    /**
+     * 注册事件监听器
+     * @name addListener
+     * @grammar editor.addListener(types,fn)  //types为事件名称,多个可用空格分隔
+     * @example
+     * editor.addListener('selectionchange',function(){
+     *      console.log("选区已经变化!");
+     * })
+     * editor.addListener('beforegetcontent aftergetcontent',function(type){
+     *         if(type == 'beforegetcontent'){
+     *             //do something
+     *         }else{
+     *             //do something
+     *         }
+     *         console.log(this.getContent) // this是注册的事件的编辑器实例
+     * })
+     */
+    addListener:function (types, listener) {
+        types = utils.trim(types).split(' ');
+        for (var i = 0, ti; ti = types[i++];) {
+            getListener(this, ti, true).push(listener);
+        }
+    },
+    /**
+     * 移除事件监听器
+     * @name removeListener
+     * @grammar editor.removeListener(types,fn)  //types为事件名称,多个可用空格分隔
+     * @example
+     * //changeCallback为方法体
+     * editor.removeListener("selectionchange",changeCallback);
+     */
+    removeListener:function (types, listener) {
+        types = utils.trim(types).split(' ');
+        for (var i = 0, ti; ti = types[i++];) {
+            utils.removeItem(getListener(this, ti) || [], listener);
+        }
+    },
+    /**
+     * 触发事件
+     * @name fireEvent
+     * @grammar editor.fireEvent(types)  //types为事件名称,多个可用空格分隔
+     * @example
+     * editor.fireEvent("selectionchange");
+     */
+    fireEvent:function (types) {
+        types = utils.trim(types).split(' ');
+        for (var i = 0, ti; ti = types[i++];) {
+            var listeners = getListener(this, ti),
+                r, t, k;
+            if (listeners) {
+                k = listeners.length;
+                while (k--) {
+                    if(!listeners[k])continue;
+                    t = listeners[k].apply(this, arguments);
+                    if(t === true){
+                        return t;
+                    }
+                    if (t !== undefined) {
+                        r = t;
+                    }
+                }
+            }
+            if (t = this['on' + ti.toLowerCase()]) {
+                r = t.apply(this, arguments);
+            }
+        }
+        return r;
+    }
+};
+/**
+ * 获得对象所拥有监听类型的所有监听器
+ * @public
+ * @function
+ * @param {Object} obj  查询监听器的对象
+ * @param {String} type 事件类型
+ * @param {Boolean} force  为true且当前所有type类型的侦听器不存在时,创建一个空监听器数组
+ * @returns {Array} 监听器数组
+ */
+function getListener(obj, type, force) {
+    var allListeners;
+    type = type.toLowerCase();
+    return ( ( allListeners = ( obj.__allListeners || force && ( obj.__allListeners = {} ) ) )
+        && ( allListeners[type] || force && ( allListeners[type] = [] ) ) );
+}
+

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1228 - 0
web/js/ueditor2/_src/core/Range.js


+ 340 - 0
web/js/ueditor2/_src/core/Selection.js

@@ -0,0 +1,340 @@
+///import editor.js
+///import core/browser.js
+///import core/dom/dom.js
+///import core/dom/dtd.js
+///import core/dom/domUtils.js
+///import core/dom/Range.js
+/**
+ * @class baidu.editor.dom.Selection    Selection类
+ */
+(function () {
+
+    function getBoundaryInformation( range, start ) {
+        var getIndex = domUtils.getNodeIndex;
+        range = range.duplicate();
+        range.collapse( start );
+        var parent = range.parentElement();
+        //如果节点里没有子节点,直接退出
+        if ( !parent.hasChildNodes() ) {
+            return  {container:parent, offset:0};
+        }
+        var siblings = parent.children,
+                child,
+                testRange = range.duplicate(),
+                startIndex = 0, endIndex = siblings.length - 1, index = -1,
+                distance;
+        while ( startIndex <= endIndex ) {
+            index = Math.floor( (startIndex + endIndex) / 2 );
+            child = siblings[index];
+            testRange.moveToElementText( child );
+            var position = testRange.compareEndPoints( 'StartToStart', range );
+            if ( position > 0 ) {
+                endIndex = index - 1;
+            } else if ( position < 0 ) {
+                startIndex = index + 1;
+            } else {
+                //trace:1043
+                return  {container:parent, offset:getIndex( child )};
+            }
+        }
+        if ( index == -1 ) {
+            testRange.moveToElementText( parent );
+            testRange.setEndPoint( 'StartToStart', range );
+            distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length;
+            siblings = parent.childNodes;
+            if ( !distance ) {
+                child = siblings[siblings.length - 1];
+                return  {container:child, offset:child.nodeValue.length};
+            }
+
+            var i = siblings.length;
+            while ( distance > 0 ){
+                distance -= siblings[ --i ].nodeValue.length;
+            }
+            return {container:siblings[i], offset:-distance};
+        }
+        testRange.collapse( position > 0 );
+        testRange.setEndPoint( position > 0 ? 'StartToStart' : 'EndToStart', range );
+        distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length;
+        if ( !distance ) {
+            return  dtd.$empty[child.tagName] || dtd.$nonChild[child.tagName] ?
+                {container:parent, offset:getIndex( child ) + (position > 0 ? 0 : 1)} :
+                {container:child, offset:position > 0 ? 0 : child.childNodes.length}
+        }
+        while ( distance > 0 ) {
+            try {
+                var pre = child;
+                child = child[position > 0 ? 'previousSibling' : 'nextSibling'];
+                distance -= child.nodeValue.length;
+            } catch ( e ) {
+                return {container:parent, offset:getIndex( pre )};
+            }
+        }
+        return  {container:child, offset:position > 0 ? -distance : child.nodeValue.length + distance}
+    }
+
+    /**
+     * 将ieRange转换为Range对象
+     * @param {Range}   ieRange    ieRange对象
+     * @param {Range}   range      Range对象
+     * @return  {Range}  range       返回转换后的Range对象
+     */
+    function transformIERangeToRange( ieRange, range ) {
+        if ( ieRange.item ) {
+            range.selectNode( ieRange.item( 0 ) );
+        } else {
+            var bi = getBoundaryInformation( ieRange, true );
+            range.setStart( bi.container, bi.offset );
+            if ( ieRange.compareEndPoints( 'StartToEnd', ieRange ) != 0 ) {
+                bi = getBoundaryInformation( ieRange, false );
+                range.setEnd( bi.container, bi.offset );
+            }
+        }
+        return range;
+    }
+
+    /**
+     * 获得ieRange
+     * @param {Selection} sel    Selection对象
+     * @return {ieRange}    得到ieRange
+     */
+    function _getIERange( sel ) {
+        var ieRange;
+        //ie下有可能报错
+        try {
+                ieRange = sel.getNative().createRange();
+        } catch ( e ) {
+            return null;
+        }
+        var el = ieRange.item ? ieRange.item( 0 ) : ieRange.parentElement();
+        if ( ( el.ownerDocument || el ) === sel.document ) {
+            return ieRange;
+        }
+        return null;
+    }
+
+    var Selection = dom.Selection = function ( doc ) {
+        var me = this, iframe;
+        me.document = doc;
+        if ( ie ) {
+            iframe = domUtils.getWindow( doc ).frameElement;
+            domUtils.on( iframe, 'beforedeactivate', function () {
+                me._bakIERange = me.getIERange();
+            } );
+            domUtils.on( iframe, 'activate', function () {
+                try {
+                    if ( !_getIERange( me ) && me._bakIERange ) {
+                        me._bakIERange.select();
+                    }
+                } catch ( ex ) {
+                }
+                me._bakIERange = null;
+            } );
+        }
+        iframe = doc = null;
+    };
+
+    Selection.prototype = {
+        /**
+         * 获取原生seleciton对象
+         * @public
+         * @function
+         * @name    baidu.editor.dom.Selection.getNative
+         * @return {Selection}    获得selection对象
+         */
+        getNative:function () {
+            var doc = this.document;
+            try {
+                return !doc ? null : ie ? doc.selection : domUtils.getWindow( doc ).getSelection();
+            } catch ( e ) {
+                return null;
+            }
+        },
+        /**
+         * 获得ieRange
+         * @public
+         * @function
+         * @name    baidu.editor.dom.Selection.getIERange
+         * @return {ieRange}    返回ie原生的Range
+         */
+        getIERange:function () {
+            var ieRange = _getIERange( this );
+            if ( !ieRange ) {
+                if ( this._bakIERange ) {
+                    return this._bakIERange;
+                }
+            }
+            return ieRange;
+        },
+
+        /**
+         * 缓存当前选区的range和选区的开始节点
+         * @public
+         * @function
+         * @name    baidu.editor.dom.Selection.cache
+         */
+        cache:function () {
+            this.clear();
+            this._cachedRange = this.getRange();
+            this._cachedStartElement = this.getStart();
+            this._cachedStartElementPath = this.getStartElementPath();
+        },
+
+        getStartElementPath:function () {
+            if ( this._cachedStartElementPath ) {
+                return this._cachedStartElementPath;
+            }
+            var start = this.getStart();
+            if ( start ) {
+                return domUtils.findParents( start, true, null, true )
+            }
+            return [];
+        },
+        /**
+         * 清空缓存
+         * @public
+         * @function
+         * @name    baidu.editor.dom.Selection.clear
+         */
+        clear:function () {
+            this._cachedStartElementPath = this._cachedRange = this._cachedStartElement = null;
+        },
+        /**
+         * 编辑器是否得到了选区
+         */
+        isFocus:function () {
+            try {
+                return browser.ie && _getIERange( this ) || !browser.ie && this.getNative().rangeCount ? true : false;
+            } catch ( e ) {
+                return false;
+            }
+
+        },
+        /**
+         * 获取选区对应的Range
+         * @public
+         * @function
+         * @name    baidu.editor.dom.Selection.getRange
+         * @returns {baidu.editor.dom.Range}    得到Range对象
+         */
+        getRange:function () {
+            var me = this;
+            function optimze( range ) {
+                var child = me.document.body.firstChild,
+                        collapsed = range.collapsed;
+                while ( child && child.firstChild ) {
+                    range.setStart( child, 0 );
+                    child = child.firstChild;
+                }
+                if ( !range.startContainer ) {
+                    range.setStart( me.document.body, 0 )
+                }
+                if ( collapsed ) {
+                    range.collapse( true );
+                }
+            }
+
+            if ( me._cachedRange != null ) {
+                return this._cachedRange;
+            }
+            var range = new baidu.editor.dom.Range( me.document );
+            if ( ie ) {
+                var nativeRange = me.getIERange();
+                if ( nativeRange ) {
+                    //备份的_bakIERange可能已经实效了,dom树发生了变化比如从源码模式切回来,所以try一下,实效就放到body开始位置
+                    try{
+                        transformIERangeToRange( nativeRange, range );
+                    }catch(e){
+                        optimze( range );
+                    }
+
+                } else {
+                    optimze( range );
+                }
+            } else {
+                var sel = me.getNative();
+                if ( sel && sel.rangeCount ) {
+                    var firstRange = sel.getRangeAt( 0 );
+                    var lastRange = sel.getRangeAt( sel.rangeCount - 1 );
+                    range.setStart( firstRange.startContainer, firstRange.startOffset ).setEnd( lastRange.endContainer, lastRange.endOffset );
+                    if ( range.collapsed && domUtils.isBody( range.startContainer ) && !range.startOffset ) {
+                        optimze( range );
+                    }
+                } else {
+                    //trace:1734 有可能已经不在dom树上了,标识的节点
+                    if ( this._bakRange && domUtils.inDoc( this._bakRange.startContainer, this.document ) ){
+                        return this._bakRange;
+                    }
+                    optimze( range );
+                }
+            }
+            return this._bakRange = range;
+        },
+
+        /**
+         * 获取开始元素,用于状态反射
+         * @public
+         * @function
+         * @name    baidu.editor.dom.Selection.getStart
+         * @return {Element}     获得开始元素
+         */
+        getStart:function () {
+            if ( this._cachedStartElement ) {
+                return this._cachedStartElement;
+            }
+            var range = ie ? this.getIERange() : this.getRange(),
+                    tmpRange,
+                    start, tmp, parent;
+            if ( ie ) {
+                if ( !range ) {
+                    //todo 给第一个值可能会有问题
+                    return this.document.body.firstChild;
+                }
+                //control元素
+                if ( range.item ){
+                    return range.item( 0 );
+                }
+                tmpRange = range.duplicate();
+                //修正ie下<b>x</b>[xx] 闭合后 <b>x|</b>xx
+                tmpRange.text.length > 0 && tmpRange.moveStart( 'character', 1 );
+                tmpRange.collapse( 1 );
+                start = tmpRange.parentElement();
+                parent = tmp = range.parentElement();
+                while ( tmp = tmp.parentNode ) {
+                    if ( tmp == start ) {
+                        start = parent;
+                        break;
+                    }
+                }
+            } else {
+                range.shrinkBoundary();
+                start = range.startContainer;
+                if ( start.nodeType == 1 && start.hasChildNodes() ){
+                    start = start.childNodes[Math.min( start.childNodes.length - 1, range.startOffset )];
+                }
+                if ( start.nodeType == 3 ){
+                    return start.parentNode;
+                }
+            }
+            return start;
+        },
+        /**
+         * 得到选区中的文本
+         * @public
+         * @function
+         * @name    baidu.editor.dom.Selection.getText
+         * @return  {String}    选区中包含的文本
+         */
+        getText:function () {
+            var nativeSel, nativeRange;
+            if ( this.isFocus() && (nativeSel = this.getNative()) ) {
+                nativeRange = browser.ie ? nativeSel.createRange() : nativeSel.getRangeAt( 0 );
+                return browser.ie ? nativeRange.text : nativeRange.toString();
+            }
+            return '';
+        },
+        clearRange : function(){
+            this.getNative()[browser.ie ? 'empty' : 'removeAllRanges']();
+        }
+    };
+})();

+ 132 - 0
web/js/ueditor2/_src/core/ajax.js

@@ -0,0 +1,132 @@
+/**
+ * @file
+ * @name UE.ajax
+ * @short Ajax
+ * @desc UEditor内置的ajax请求模块
+ * @import core/utils.js
+ * @user: taoqili
+ * @date: 11-8-18
+ * @time: 下午3:18
+ */
+UE.ajax = function() {
+    /**
+     * 创建一个ajaxRequest对象
+     */
+    var fnStr = 'XMLHttpRequest()';
+    try {
+        new ActiveXObject("Msxml2.XMLHTTP");
+        fnStr = 'ActiveXObject(\'Msxml2.XMLHTTP\')';
+    } catch (e) {
+        try {
+            new ActiveXObject("Microsoft.XMLHTTP");
+            fnStr = 'ActiveXObject(\'Microsoft.XMLHTTP\')'
+        } catch (e) {
+        }
+    }
+    var creatAjaxRequest = new Function('return new ' + fnStr);
+
+
+    /**
+     * 将json参数转化成适合ajax提交的参数列表
+     * @param json
+     */
+    function json2str(json) {
+        var strArr = [];
+        for (var i in json) {
+            //忽略默认的几个参数
+            if(i=="method" || i=="timeout" || i=="async") continue;
+            //传递过来的对象和函数不在提交之列
+            if (!((typeof json[i]).toLowerCase() == "function" || (typeof json[i]).toLowerCase() == "object")) {
+                strArr.push( encodeURIComponent(i) + "="+encodeURIComponent(json[i]) );
+            }
+        }
+        return strArr.join("&");
+
+    }
+
+
+    return {
+		/**
+         * @name request
+         * @desc 发出ajax请求,ajaxOpt中默认包含method,timeout,async,data,onsuccess以及onerror等六个,支持自定义添加参数
+         * @grammar UE.ajax.request(url,ajaxOpt);
+         * @example
+         * UE.ajax.request('http://www.xxxx.com/test.php',{
+         *     //可省略,默认POST
+         *     method:'POST',
+         *     //可以自定义参数
+         *     content:'这里是提交的内容',
+         *     //也可以直接传json,但是只能命名为data,否则当做一般字符串处理
+         *     data:{
+         *         name:'UEditor',
+         *         age:'1'
+         *     }
+         *     onsuccess:function(xhr){
+         *         console.log(xhr.responseText);
+         *     },
+         *     onerror:function(xhr){
+         *         console.log(xhr.responseText);
+         *     }
+         * })
+		 * @param ajaxOptions
+		 */
+		request:function(url, ajaxOptions) {
+            var ajaxRequest = creatAjaxRequest(),
+                //是否超时
+                timeIsOut = false,
+                //默认参数
+                defaultAjaxOptions = {
+                    method:"POST",
+                    timeout:5000,
+                    async:true,
+                    data:{},//需要传递对象的话只能覆盖
+                    onsuccess:function() {
+                    },
+                    onerror:function() {
+                    }
+                };
+
+			if (typeof url === "object") {
+				ajaxOptions = url;
+				url = ajaxOptions.url;
+			}
+			if (!ajaxRequest || !url) return;
+			var ajaxOpts = ajaxOptions ? utils.extend(defaultAjaxOptions,ajaxOptions) : defaultAjaxOptions;
+
+			var submitStr = json2str(ajaxOpts);  // { name:"Jim",city:"Beijing" } --> "name=Jim&city=Beijing"
+			//如果用户直接通过data参数传递json对象过来,则也要将此json对象转化为字符串
+			if (!utils.isEmptyObject(ajaxOpts.data)){
+                submitStr += (submitStr? "&":"") + json2str(ajaxOpts.data);
+			}
+            //超时检测
+            var timerID = setTimeout(function() {
+                if (ajaxRequest.readyState != 4) {
+                    timeIsOut = true;
+                    ajaxRequest.abort();
+                    clearTimeout(timerID);
+                }
+            }, ajaxOpts.timeout);
+
+			var method = ajaxOpts.method.toUpperCase();
+            var str = url + (url.indexOf("?")==-1?"?":"&") + (method=="POST"?"":submitStr+ "&noCache=" + +new Date);
+			ajaxRequest.open(method, str, ajaxOpts.async);
+			ajaxRequest.onreadystatechange = function() {
+				if (ajaxRequest.readyState == 4) {
+					if (!timeIsOut && ajaxRequest.status == 200) {
+						ajaxOpts.onsuccess(ajaxRequest);
+					} else {
+						ajaxOpts.onerror(ajaxRequest);
+					}
+				}
+			};
+			if (method == "POST") {
+				ajaxRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+				ajaxRequest.send(submitStr);
+			} else {
+				ajaxRequest.send(null);
+			}
+		}
+	};
+
+
+}();

+ 167 - 0
web/js/ueditor2/_src/core/browser.js

@@ -0,0 +1,167 @@
+/**
+ * @file
+ * @name UE.browser
+ * @short Browser
+ * @desc UEditor中采用的浏览器判断模块
+ */
+var browser = UE.browser = function(){
+    var agent = navigator.userAgent.toLowerCase(),
+        opera = window.opera,
+        browser = {
+        /**
+         * 检测浏览器是否为IE
+         * @name ie
+         * @grammar UE.browser.ie  => true|false
+         */
+        ie		: !!window.ActiveXObject,
+
+        /**
+         * 检测浏览器是否为Opera
+         * @name opera
+         * @grammar UE.browser.opera  => true|false
+         */
+        opera	: ( !!opera && opera.version ),
+
+        /**
+         * 检测浏览器是否为webkit内核
+         * @name webkit
+         * @grammar UE.browser.webkit  => true|false
+         */
+        webkit	: ( agent.indexOf( ' applewebkit/' ) > -1 ),
+
+        /**
+         * 检测浏览器是否为mac系统下的浏览器
+         * @name mac
+         * @grammar UE.browser.mac  => true|false
+         */
+        mac	: ( agent.indexOf( 'macintosh' ) > -1 ),
+
+        /**
+         * 检测浏览器是否处于怪异模式
+         * @name quirks
+         * @grammar UE.browser.quirks  => true|false
+         */
+        quirks : ( document.compatMode == 'BackCompat' )
+    };
+    /**
+     * 检测浏览器是否处为gecko内核
+     * @name gecko
+     * @grammar UE.browser.gecko  => true|false
+     */
+    browser.gecko =( navigator.product == 'Gecko' && !browser.webkit && !browser.opera );
+
+    var version = 0;
+
+    // Internet Explorer 6.0+
+    if ( browser.ie ){
+        version = parseFloat( agent.match( /msie (\d+)/ )[1] );
+        /**
+         * 检测浏览器是否为 IE9 模式
+         * @name ie9Compat
+         * @grammar UE.browser.ie9Compat  => true|false
+         */
+        browser.ie9Compat = document.documentMode == 9;
+        /**
+         * 检测浏览器是否为 IE8 浏览器
+         * @name ie8
+         * @grammar     UE.browser.ie8  => true|false
+         */
+        browser.ie8 = !!document.documentMode;
+
+        /**
+         * 检测浏览器是否为 IE8 模式
+         * @name ie8Compat
+         * @grammar     UE.browser.ie8Compat  => true|false
+         */
+        browser.ie8Compat = document.documentMode == 8;
+
+        /**
+         * 检测浏览器是否运行在 兼容IE7模式
+         * @name ie7Compat
+         * @grammar     UE.browser.ie7Compat  => true|false
+         */
+        browser.ie7Compat = ( ( version == 7 && !document.documentMode )
+                || document.documentMode == 7 );
+
+        /**
+         * 检测浏览器是否IE6模式或怪异模式
+         * @name ie6Compat
+         * @grammar     UE.browser.ie6Compat  => true|false
+         */
+        browser.ie6Compat = ( version < 7 || browser.quirks );
+
+    }
+
+    // Gecko.
+    if ( browser.gecko ){
+        var geckoRelease = agent.match( /rv:([\d\.]+)/ );
+        if ( geckoRelease )
+        {
+            geckoRelease = geckoRelease[1].split( '.' );
+            version = geckoRelease[0] * 10000 + ( geckoRelease[1] || 0 ) * 100 + ( geckoRelease[2] || 0 ) * 1;
+        }
+    }
+    /**
+     * 检测浏览器是否为chrome
+     * @name chrome
+     * @grammar     UE.browser.chrome  => true|false
+     */
+    if (/chrome\/(\d+\.\d)/i.test(agent)) {
+        browser.chrome = + RegExp['\x241'];
+    }
+    /**
+     * 检测浏览器是否为safari
+     * @name safari
+     * @grammar     UE.browser.safari  => true|false
+     */
+    if(/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(agent) && !/chrome/i.test(agent)){
+    	browser.safari = + (RegExp['\x241'] || RegExp['\x242']);
+    }
+
+
+    // Opera 9.50+
+    if ( browser.opera )
+        version = parseFloat( opera.version() );
+
+    // WebKit 522+ (Safari 3+)
+    if ( browser.webkit )
+        version = parseFloat( agent.match( / applewebkit\/(\d+)/ )[1] );
+
+    /**
+     * 浏览器版本判断
+     * IE系列返回值为5,6,7,8,9,10等
+     * gecko系列会返回10900,158900等.
+     * webkit系列会返回其build号 (如 522等).
+     * @name version
+     * @grammar     UE.browser.version  => number
+     * @example
+     * if ( UE.browser.ie && UE.browser.version == 6 ){
+     *     alert( "Ouch!居然是万恶的IE6!" );
+     * }
+     */
+    browser.version = version;
+
+    /**
+     * 是否是兼容模式的浏览器
+     * @name isCompatible
+     * @grammar  UE.browser.isCompatible  => true|false
+     * @example
+     * if ( UE.browser.isCompatible ){
+     *     alert( "你的浏览器相当不错哦!" );
+     * }
+     */
+    browser.isCompatible =
+        !browser.mobile && (
+        ( browser.ie && version >= 6 ) ||
+        ( browser.gecko && version >= 10801 ) ||
+        ( browser.opera && version >= 9.5 ) ||
+        ( browser.air && version >= 1 ) ||
+        ( browser.webkit && version >= 522 ) ||
+        false );
+    return browser;
+}();
+//快捷方式
+var ie = browser.ie,
+    webkit = browser.webkit,
+    gecko = browser.gecko,
+    opera = browser.opera;

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1285 - 0
web/js/ueditor2/_src/core/domUtils.js


+ 186 - 0
web/js/ueditor2/_src/core/dtd.js

@@ -0,0 +1,186 @@
+///import editor.js
+///import core/dom/dom.js
+/**
+ * dtd html语义化的体现类
+ * @constructor
+ * @namespace dtd
+ */
+var dtd = dom.dtd = (function() {
+    function _( s ) {
+        for (var k in s) {
+            s[k.toUpperCase()] = s[k];
+        }
+        return s;
+    }
+    function X( t ) {
+        var a = arguments;
+        for ( var i=1; i<a.length; i++ ) {
+            var x = a[i];
+            for ( var k in x ) {
+                if (!t.hasOwnProperty(k)) {
+                    t[k] = x[k];
+                }
+            }
+        }
+        return t;
+    }
+    var A = _({isindex:1,fieldset:1}),
+        B = _({input:1,button:1,select:1,textarea:1,label:1}),
+        C = X( _({a:1}), B ),
+        D = X( {iframe:1}, C ),
+        E = _({hr:1,ul:1,menu:1,div:1,blockquote:1,noscript:1,table:1,center:1,address:1,dir:1,pre:1,h5:1,dl:1,h4:1,noframes:1,h6:1,ol:1,h1:1,h3:1,h2:1}),
+        F = _({ins:1,del:1,script:1,style:1}),
+        G = X( _({b:1,acronym:1,bdo:1,'var':1,'#':1,abbr:1,code:1,br:1,i:1,cite:1,kbd:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,dfn:1,span:1}), F ),
+        H = X( _({sub:1,img:1,embed:1,object:1,sup:1,basefont:1,map:1,applet:1,font:1,big:1,small:1}), G ),
+        I = X( _({p:1}), H ),
+        J = X( _({iframe:1}), H, B ),
+        K = _({img:1,embed:1,noscript:1,br:1,kbd:1,center:1,button:1,basefont:1,h5:1,h4:1,samp:1,h6:1,ol:1,h1:1,h3:1,h2:1,form:1,font:1,'#':1,select:1,menu:1,ins:1,abbr:1,label:1,code:1,table:1,script:1,cite:1,input:1,iframe:1,strong:1,textarea:1,noframes:1,big:1,small:1,span:1,hr:1,sub:1,bdo:1,'var':1,div:1,object:1,sup:1,strike:1,dir:1,map:1,dl:1,applet:1,del:1,isindex:1,fieldset:1,ul:1,b:1,acronym:1,a:1,blockquote:1,i:1,u:1,s:1,tt:1,address:1,q:1,pre:1,p:1,em:1,dfn:1}),
+
+        L = X( _({a:0}), J ),//a不能被切开,所以把他
+        M = _({tr:1}),
+        N = _({'#':1}),
+        O = X( _({param:1}), K ),
+        P = X( _({form:1}), A, D, E, I ),
+        Q = _({li:1}),
+        R = _({style:1,script:1}),
+        S = _({base:1,link:1,meta:1,title:1}),
+        T = X( S, R ),
+        U = _({head:1,body:1}),
+        V = _({html:1});
+
+    var block = _({address:1,blockquote:1,center:1,dir:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,isindex:1,menu:1,noframes:1,ol:1,p:1,pre:1,table:1,ul:1}),
+        //针对优酷的embed他添加了结束标识,导致粘贴进来会变成两个,暂时去掉 ,embed:1
+        empty =  _({area:1,base:1,br:1,col:1,hr:1,img:1,input:1,link:1,meta:1,param:1,embed:1});
+
+    return  _({
+
+        // $ 表示自定的属性
+
+        // body外的元素列表.
+        $nonBodyContent: X( V, U, S ),
+
+        //块结构元素列表
+        $block : block,
+
+        //内联元素列表
+        $inline : L,
+
+        $body : X( _({script:1,style:1}), block ),
+
+        $cdata : _({script:1,style:1}),
+
+        //自闭和元素
+        $empty : empty,
+
+        //不是自闭合,但不能让range选中里边
+        $nonChild : _({iframe:1,textarea:1}),
+        //列表元素列表
+        $listItem : _({dd:1,dt:1,li:1}),
+
+        //列表根元素列表
+        $list: _({ul:1,ol:1,dl:1}),
+
+        //不能认为是空的元素
+        $isNotEmpty : _({table:1,ul:1,ol:1,dl:1,iframe:1,area:1,base:1,col:1,hr:1,img:1,embed:1,input:1,link:1,meta:1,param:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,textarea:1,span:1,select:1}),
+
+        //如果没有子节点就可以删除的元素列表,像span,a
+        $removeEmpty : _({a:1,abbr:1,acronym:1,address:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,s:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,'var':1}),
+
+        $removeEmptyBlock : _({'p':1,'div':1}),
+
+        //在table元素里的元素列表
+        $tableContent : _({caption:1,col:1,colgroup:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1,table:1}),
+        //不转换的标签
+        $notTransContent : _({pre:1,script:1,style:1,textarea:1}),
+        html: U,
+        head: T,
+        style: N,
+        script: N,
+        body: P,
+        base: {},
+        link: {},
+        meta: {},
+        title: N,
+        col : {},
+        tr : _({td:1,th:1}),
+        img : {},
+        embed: {},
+        colgroup : _({thead:1,col:1,tbody:1,tr:1,tfoot:1}),
+        noscript : P,
+        td : P,
+        br : {},
+        th : P,
+        center : P,
+        kbd : L,
+        button : X( I, E ),
+        basefont : {},
+        h5 : L,
+        h4 : L,
+        samp : L,
+        h6 : L,
+        ol : Q,
+        h1 : L,
+        h3 : L,
+        option : N,
+        h2 : L,
+        form : X( A, D, E, I ),
+        select : _({optgroup:1,option:1}),
+        font : L,
+        ins : L,
+        menu : Q,
+        abbr : L,
+        label : L,
+        table : _({thead:1,col:1,tbody:1,tr:1,colgroup:1,caption:1,tfoot:1}),
+        code : L,
+        tfoot : M,
+        cite : L,
+        li : P,
+        input : {},
+        iframe : P,
+        strong : L,
+        textarea : N,
+        noframes : P,
+        big : L,
+        small : L,
+        span :_({'#':1,br:1}),
+        hr : L,
+        dt : L,
+        sub : L,
+        optgroup : _({option:1}),
+        param : {},
+        bdo : L,
+        'var' : L,
+        div : P,
+        object : O,
+        sup : L,
+        dd : P,
+        strike : L,
+        area : {},
+        dir : Q,
+        map : X( _({area:1,form:1,p:1}), A, F, E ),
+        applet : O,
+        dl : _({dt:1,dd:1}),
+        del : L,
+        isindex : {},
+        fieldset : X( _({legend:1}), K ),
+        thead : M,
+        ul : Q,
+        acronym : L,
+        b : L,
+        a : X( _({a:1}), J ),
+        blockquote :X(_({td:1,tr:1,tbody:1,li:1}),P),
+        caption : L,
+        i : L,
+        u : L,
+        tbody : M,
+        s : L,
+        address : X( D, I ),
+        tt : L,
+        legend : L,
+        q : L,
+        pre : X( G, C ),
+        p : X(_({'a':1}),L),
+        em :L,
+        dfn : L
+    });
+})();

+ 167 - 0
web/js/ueditor2/_src/core/filterword.js

@@ -0,0 +1,167 @@
+/**
+ * @file
+ * @name UE.filterWord
+ * @short filterWord
+ * @desc 用来过滤word粘贴过来的字符串
+ * @import editor.js,core/utils.js
+ * @anthor zhanyi
+ */
+var filterWord = UE.filterWord = function () {
+
+    //是否是word过来的内容
+    function isWordDocument( str ) {
+        return /(class="?Mso|style="[^"]*\bmso\-|w:WordDocument|<v:)/ig.test( str );
+    }
+    //去掉小数
+    function transUnit( v ) {
+        v = v.replace( /[\d.]+\w+/g, function ( m ) {
+            return utils.transUnitToPx(m);
+        } );
+        return v;
+    }
+
+    function filterPasteWord( str ) {
+        return str.replace( /[\t\r\n]+/g, "" )
+                .replace( /<!--[\s\S]*?-->/ig, "" )
+                //转换图片
+                .replace(/<v:shape [^>]*>[\s\S]*?.<\/v:shape>/gi,function(str){
+                    //opera能自己解析出image所这里直接返回空
+                    if(browser.opera){
+                        return '';
+                    }
+                    try{
+                        var width = str.match(/width:([ \d.]*p[tx])/i)[1],
+                            height = str.match(/height:([ \d.]*p[tx])/i)[1],
+                            src =  str.match(/src=\s*"([^"]*)"/i)[1];
+                        return '<img width="'+ transUnit(width) +'" height="'+transUnit(height) +'" src="' + src + '" />';
+                    } catch(e){
+                        return '';
+                    }
+                })
+                //针对wps添加的多余标签处理
+                .replace(/<\/?div[^>]*>/g,'')
+                //去掉多余的属性
+                .replace( /v:\w+=(["']?)[^'"]+\1/g, '' )
+                .replace( /<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|xml|meta|link|style|\w+:\w+)(?=[\s\/>]))[^>]*>/gi, "" )
+                .replace( /<p [^>]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi, "<p><strong>$1</strong></p>" )
+                //去掉多余的属性
+                .replace( /\s+(class|lang|align)\s*=\s*(['"]?)[\w-]+\2/ig, "" )
+                //清除多余的font/span不能匹配&nbsp;有可能是空格
+                .replace( /<(font|span)[^>]*>\s*<\/\1>/gi, '' )
+                //处理style的问题
+                .replace( /(<[a-z][^>]*)\sstyle=(["'])([^\2]*?)\2/gi, function( str, tag, tmp, style ) {
+                    var n = [],
+                        s = style.replace( /^\s+|\s+$/, '' )
+                            .replace(/&#39;/g,'\'')
+                            .replace( /&quot;/gi, "'" )
+                            .split( /;\s*/g );
+
+                    for ( var i = 0,v; v = s[i];i++ ) {
+
+                        var name, value,
+                            parts = v.split( ":" );
+
+                        if ( parts.length == 2 ) {
+                            name = parts[0].toLowerCase();
+                            value = parts[1].toLowerCase();
+                            if(/^(background)\w*/.test(name) && value.replace(/(initial|\s)/g,'').length == 0
+                                ||
+                                /^(margin)\w*/.test(name) && /^0\w+$/.test(value)
+                            ){
+                                continue;
+                            }
+
+                            switch ( name ) {
+                                case "mso-padding-alt":
+                                case "mso-padding-top-alt":
+                                case "mso-padding-right-alt":
+                                case "mso-padding-bottom-alt":
+                                case "mso-padding-left-alt":
+                                case "mso-margin-alt":
+                                case "mso-margin-top-alt":
+                                case "mso-margin-right-alt":
+                                case "mso-margin-bottom-alt":
+                                case "mso-margin-left-alt":
+                                //ie下会出现挤到一起的情况
+                               //case "mso-table-layout-alt":
+                                case "mso-height":
+                                case "mso-width":
+                                case "mso-vertical-align-alt":
+                                    //trace:1819 ff下会解析出padding在table上
+                                    if(!/<table/.test(tag))
+                                        n[i] = name.replace( /^mso-|-alt$/g, "" ) + ":" + transUnit( value );
+                                    continue;
+                                case "horiz-align":
+                                    n[i] = "text-align:" + value;
+                                    continue;
+
+                                case "vert-align":
+                                    n[i] = "vertical-align:" + value;
+                                    continue;
+
+                                case "font-color":
+                                case "mso-foreground":
+                                    n[i] = "color:" + value;
+                                    continue;
+
+                                case "mso-background":
+                                case "mso-highlight":
+                                    n[i] = "background:" + value;
+                                    continue;
+
+                                case "mso-default-height":
+                                    n[i] = "min-height:" + transUnit( value );
+                                    continue;
+
+                                case "mso-default-width":
+                                    n[i] = "min-width:" + transUnit( value );
+                                    continue;
+
+                                case "mso-padding-between-alt":
+                                    n[i] = "border-collapse:separate;border-spacing:" + transUnit( value );
+                                    continue;
+
+                                case "text-line-through":
+                                    if ( (value == "single") || (value == "double") ) {
+                                        n[i] = "text-decoration:line-through";
+                                    }
+                                    continue;
+                                case "mso-zero-height":
+                                    if ( value == "yes" ) {
+                                        n[i] = "display:none";
+                                    }
+                                    continue;
+                                case 'background':
+                                    if(value == 'initial'){
+
+                                    }
+                                    break;
+                                case 'margin':
+                                    if ( !/[1-9]/.test( value ) ) {
+                                        continue;
+                                    }
+
+                            }
+
+                            if ( /^(mso|column|font-emph|lang|layout|line-break|list-image|nav|panose|punct|row|ruby|sep|size|src|tab-|table-border|text-(?:decor|trans)|top-bar|version|vnd|word-break)/.test( name )
+                                ||
+                                /text\-indent|padding|margin/.test(name) && /\-[\d.]+/.test(value)
+                            ) {
+                                continue;
+                            }
+
+                            n[i] = name + ":" + parts[1];
+                        }
+                    }
+                    return tag + (n.length ? ' style="' + n.join( ';').replace(/;{2,}/g,';') + '"' : '');
+                })
+            .replace(/[\d.]+(cm|pt)/g,function(str){
+                return utils.transUnitToPx(str)
+            })
+
+    }
+
+    return function ( html ) {
+        return (isWordDocument( html ) ? filterPasteWord( html ) : html).replace( />[ \t\r\n]*</g, '><' );
+    };
+}();

+ 613 - 0
web/js/ueditor2/_src/core/utils.js

@@ -0,0 +1,613 @@
+/**
+ * @file
+ * @name UE.Utils
+ * @short Utils
+ * @desc UEditor封装使用的静态工具函数
+ * @import editor.js
+ */
+var utils = UE.utils = {
+    /**
+     * 遍历数组,对象,nodeList
+     * @name each
+     * @grammar UE.utils.each(obj,iterator,[context])
+     * @since 1.2.4+
+     * @desc
+     * * obj 要遍历的对象
+     * * iterator 遍历的方法,方法的第一个是遍历的值,第二个是索引,第三个是obj
+     * * context  iterator的上下文
+     * @example
+     * UE.utils.each([1,2],function(v,i){
+     *     console.log(v)//值
+     *     console.log(i)//索引
+     * })
+     * UE.utils.each(document.getElementsByTagName('*'),function(n){
+     *     console.log(n.tagName)
+     * })
+     */
+    each : function(obj, iterator, context) {
+        if (obj == null) return;
+        if (obj.length === +obj.length) {
+            for (var i = 0, l = obj.length; i < l; i++) {
+                if(iterator.call(context, obj[i], i, obj) === false)
+                    return false;
+            }
+        } else {
+            for (var key in obj) {
+                if (obj.hasOwnProperty(key)) {
+                    if(iterator.call(context, obj[key], key, obj) === false)
+                        return false;
+                }
+            }
+        }
+    },
+
+    makeInstance:function (obj) {
+        var noop = new Function();
+        noop.prototype = obj;
+        obj = new noop;
+        noop.prototype = null;
+        return obj;
+    },
+    /**
+     * 将source对象中的属性扩展到target对象上
+     * @name extend
+     * @grammar UE.utils.extend(target,source)  => Object  //覆盖扩展
+     * @grammar UE.utils.extend(target,source,true)  ==> Object  //保留扩展
+     */
+    extend:function (t, s, b) {
+        if (s) {
+            for (var k in s) {
+                if (!b || !t.hasOwnProperty(k)) {
+                    t[k] = s[k];
+                }
+            }
+        }
+        return t;
+    },
+
+    /**
+     * 模拟继承机制,subClass继承superClass
+     * @name inherits
+     * @grammar UE.utils.inherits(subClass,superClass) => subClass
+     * @example
+     * function SuperClass(){
+     *     this.name = "小李";
+     * }
+     * SuperClass.prototype = {
+     *     hello:function(str){
+     *         console.log(this.name + str);
+     *     }
+     * }
+     * function SubClass(){
+     *     this.name = "小张";
+     * }
+     * UE.utils.inherits(SubClass,SuperClass);
+     * var sub = new SubClass();
+     * sub.hello("早上好!"); ==> "小张早上好!"
+     */
+    inherits:function (subClass, superClass) {
+        var oldP = subClass.prototype,
+            newP = utils.makeInstance(superClass.prototype);
+        utils.extend(newP, oldP, true);
+        subClass.prototype = newP;
+        return (newP.constructor = subClass);
+    },
+
+    /**
+     * 用指定的context作为fn上下文,也就是this
+     * @name bind
+     * @grammar UE.utils.bind(fn,context)  =>  fn
+     */
+    bind:function (fn, context) {
+        return function () {
+            return fn.apply(context, arguments);
+        };
+    },
+
+    /**
+     * 创建延迟delay执行的函数fn
+     * @name defer
+     * @grammar UE.utils.defer(fn,delay)  =>fn   //延迟delay毫秒执行fn,返回fn
+     * @grammar UE.utils.defer(fn,delay,exclusion)  =>fn   //延迟delay毫秒执行fn,若exclusion为真,则互斥执行fn
+     * @example
+     * function test(){
+     *     console.log("延迟输出!");
+     * }
+     * //非互斥延迟执行
+     * var testDefer = UE.utils.defer(test,1000);
+     * testDefer();   =>  "延迟输出!";
+     * testDefer();   =>  "延迟输出!";
+     * //互斥延迟执行
+     * var testDefer1 = UE.utils.defer(test,1000,true);
+     * testDefer1();   =>  //本次不执行
+     * testDefer1();   =>  "延迟输出!";
+     */
+    defer:function (fn, delay, exclusion) {
+        var timerID;
+        return function () {
+            if (exclusion) {
+                clearTimeout(timerID);
+            }
+            timerID = setTimeout(fn, delay);
+        };
+    },
+
+    /**
+     * 查找元素item在数组array中的索引, 若找不到返回-1
+     * @name indexOf
+     * @grammar UE.utils.indexOf(array,item)  => index|-1  //默认从数组开头部开始搜索
+     * @grammar UE.utils.indexOf(array,item,start)  => index|-1  //start指定开始查找的位置
+     */
+    indexOf:function (array, item, start) {
+        var index = -1;
+        start = this.isNumber(start) ? start : 0;
+        this.each(array,function(v,i){
+            if(i >= start && v === item){
+                index = i;
+                return false;
+            }
+        });
+        return index;
+    },
+
+    /**
+     * 移除数组array中的元素item
+     * @name removeItem
+     * @grammar UE.utils.removeItem(array,item)
+     */
+    removeItem:function (array, item) {
+        for (var i = 0, l = array.length; i < l; i++) {
+            if (array[i] === item) {
+                array.splice(i, 1);
+                i--;
+            }
+        }
+    },
+    
+    /**
+	 * json对象转为string
+	 * @param o
+	 * @returns {String}
+	 */
+	json2str:function(o){
+		var arr=[];
+		var fmt = function(s) {
+	         if (typeof s == 'object' && s != null) return utils.json2str(s);
+	         return /^(string)$/.test(typeof s) ? "'" + s + "'" : s;
+	     }
+	     for (var i in o) arr.push( i + ":" + fmt(o[i]));
+	     return '{' + arr.join(',') + '}';
+	},
+
+    /**
+     * 删除字符串str的首尾空格
+     * @name trim
+     * @grammar UE.utils.trim(str) => String
+     */
+    trim:function (str) {
+        return str.replace(/(^[ \t\n\r]+)|([ \t\n\r]+$)/g, '');
+    },
+
+    /**
+     * 将字符串list(以','分隔)或者数组list转成哈希对象
+     * @name listToMap
+     * @grammar UE.utils.listToMap(list)  => Object  //Object形如{test:1,br:1,textarea:1}
+     */
+    listToMap:function (list) {
+        if (!list)return {};
+        list = utils.isArray(list) ? list : list.split(',');
+        for (var i = 0, ci, obj = {}; ci = list[i++];) {
+            obj[ci.toUpperCase()] = obj[ci] = 1;
+        }
+        return obj;
+    },
+
+    /**
+     * 将str中的html符号转义,默认将转义''&<">''四个字符,可自定义reg来确定需要转义的字符
+     * @name unhtml
+     * @grammar UE.utils.unhtml(str);  => String
+     * @grammar UE.utils.unhtml(str,reg)  => String
+     * @example
+     * var html = '<body>You say:"你好!Baidu & UEditor!"</body>';
+     * UE.utils.unhtml(html);   ==>  &lt;body&gt;You say:&quot;你好!Baidu &amp; UEditor!&quot;&lt;/body&gt;
+     * UE.utils.unhtml(html,/[<>]/g)  ==>  &lt;body&gt;You say:"你好!Baidu & UEditor!"&lt;/body&gt;
+     */
+    unhtml:function (str, reg) {
+        return str ? str.replace(reg || /[&<">]/g, function (m) {
+            return {
+                '<':'&lt;',
+                '&':'&amp;',
+                '"':'&quot;',
+                '>':'&gt;'
+            }[m]
+        }) : '';
+    },
+    /**
+     * 将str中的转义字符还原成html字符
+     * @name html
+     * @grammar UE.utils.html(str)  => String   //详细参见<code><a href = '#unhtml'>unhtml</a></code>
+     */
+    html:function (str) {
+        return str ? str.replace(/&((g|l|quo)t|amp);/g, function (m) {
+            return {
+                '&lt;':'<',
+                '&amp;':'&',
+                '&quot;':'"',
+                '&gt;':'>'
+            }[m]
+        }) : '';
+    },
+    /**
+     * 将css样式转换为驼峰的形式。如font-size => fontSize
+     * @name cssStyleToDomStyle
+     * @grammar UE.utils.cssStyleToDomStyle(cssName)  => String
+     */
+    cssStyleToDomStyle:function () {
+        var test = document.createElement('div').style,
+            cache = {
+                'float':test.cssFloat != undefined ? 'cssFloat' : test.styleFloat != undefined ? 'styleFloat' : 'float'
+            };
+
+        return function (cssName) {
+            return cache[cssName] || (cache[cssName] = cssName.toLowerCase().replace(/-./g, function (match) {
+                return match.charAt(1).toUpperCase();
+            }));
+        };
+    }(),
+    /**
+     * 动态加载文件到doc中,并依据obj来设置属性,加载成功后执行回调函数fn
+     * @name loadFile
+     * @grammar UE.utils.loadFile(doc,obj)
+     * @grammar UE.utils.loadFile(doc,obj,fn)
+     * @example
+     * //指定加载到当前document中一个script文件,加载成功后执行function
+     * utils.loadFile( document, {
+     *     src:"test.js",
+     *     tag:"script",
+     *     type:"text/javascript",
+     *     defer:"defer"
+     * }, function () {
+     *     console.log('加载成功!')
+     * });
+     */
+    loadFile:function () {
+        var tmpList = [];
+        function getItem(doc,obj){
+            try{
+                for(var i= 0,ci;ci=tmpList[i++];){
+                    if(ci.doc === doc && ci.url == (obj.src || obj.href)){
+                        return ci;
+                    }
+                }
+            }catch(e){
+                return null;
+            }
+
+        }
+        return function (doc, obj, fn) {
+            var item = getItem(doc,obj);
+            if (item) {
+                if(item.ready){
+                    fn && fn();
+                }else{
+                    item.funs.push(fn)
+                }
+                return;
+            }
+            tmpList.push({
+                doc:doc,
+                url:obj.src||obj.href,
+                funs:[fn]
+            });
+            if (!doc.body) {
+                var html = [];
+                for(var p in obj){
+                    if(p == 'tag')continue;
+                    html.push(p + '="' + obj[p] + '"')
+                }
+                doc.write('<' + obj.tag + ' ' + html.join(' ') + ' ></'+obj.tag+'>');
+                return;
+            }
+            if (obj.id && doc.getElementById(obj.id)) {
+                return;
+            }
+            var element = doc.createElement(obj.tag);
+            delete obj.tag;
+            for (var p in obj) {
+                element.setAttribute(p, obj[p]);
+            }
+            element.onload = element.onreadystatechange = function () {
+                if (!this.readyState || /loaded|complete/.test(this.readyState)) {
+                    item = getItem(doc,obj);
+                    if (item.funs.length > 0) {
+                        item.ready = 1;
+                        for (var fi; fi = item.funs.pop();) {
+                            fi();
+                        }
+                    }
+                    element.onload = element.onreadystatechange = null;
+                }
+            };
+            element.onerror = function(){
+                throw Error('The load '+(obj.href||obj.src)+' fails,check the url settings of file editor_config.js ')
+            };
+            doc.getElementsByTagName("head")[0].appendChild(element);
+        }
+    }(),
+    /**
+     * 判断obj对象是否为空
+     * @name isEmptyObject
+     * @grammar UE.utils.isEmptyObject(obj)  => true|false
+     * @example
+     * UE.utils.isEmptyObject({}) ==>true
+     * UE.utils.isEmptyObject([]) ==>true
+     * UE.utils.isEmptyObject("") ==>true
+     */
+    isEmptyObject:function (obj) {
+        if (obj == null) return true;
+        if (this.isArray(obj) || this.isString(obj)) return obj.length === 0;
+        for (var key in obj) if (obj.hasOwnProperty(key)) return false;
+        return true;
+    },
+
+    /**
+     * 统一将颜色值使用16进制形式表示
+     * @name fixColor
+     * @grammar UE.utils.fixColor(name,value) => value
+     * @example
+     * rgb(255,255,255)  => "#ffffff"
+     */
+    fixColor:function (name, value) {
+        if (/color/i.test(name) && /rgba?/.test(value)) {
+            var array = value.split(",");
+            if (array.length > 3)
+                return "";
+            value = "#";
+            for (var i = 0, color; color = array[i++];) {
+                color = parseInt(color.replace(/[^\d]/gi, ''), 10).toString(16);
+                value += color.length == 1 ? "0" + color : color;
+            }
+            value = value.toUpperCase();
+        }
+        return  value;
+    },
+    /**
+     * 只针对border,padding,margin做了处理,因为性能问题
+     * @public
+     * @function
+     * @param {String}    val style字符串
+     */
+    optCss:function (val) {
+        var padding, margin, border;
+        val = val.replace(/(padding|margin|border)\-([^:]+):([^;]+);?/gi, function (str, key, name, val) {
+            if (val.split(' ').length == 1) {
+                switch (key) {
+                    case 'padding':
+                        !padding && (padding = {});
+                        padding[name] = val;
+                        return '';
+                    case 'margin':
+                        !margin && (margin = {});
+                        margin[name] = val;
+                        return '';
+                    case 'border':
+                        return val == 'initial' ? '' : str;
+                }
+            }
+            return str;
+        });
+
+        function opt(obj, name) {
+            if (!obj) {
+                return '';
+            }
+            var t = obj.top , b = obj.bottom, l = obj.left, r = obj.right, val = '';
+            if (!t || !l || !b || !r) {
+                for (var p in obj) {
+                    val += ';' + name + '-' + p + ':' + obj[p] + ';';
+                }
+            } else {
+                val += ';' + name + ':' +
+                    (t == b && b == l && l == r ? t :
+                        t == b && l == r ? (t + ' ' + l) :
+                            l == r ? (t + ' ' + l + ' ' + b) : (t + ' ' + r + ' ' + b + ' ' + l)) + ';'
+            }
+            return val;
+        }
+
+        val += opt(padding, 'padding') + opt(margin, 'margin');
+        return val.replace(/^[ \n\r\t;]*|[ \n\r\t]*$/, '').replace(/;([ \n\r\t]+)|\1;/g, ';')
+            .replace(/(&((l|g)t|quot|#39))?;{2,}/g, function (a, b) {
+                return b ? b + ";;" : ';'
+            });
+    },
+    /**
+     * 深度克隆对象,从source到target
+     * @name clone
+     * @grammar UE.utils.clone(source) => anthorObj 新的对象是完整的source的副本
+     * @grammar UE.utils.clone(source,target) => target包含了source的所有内容,重名会覆盖
+     */
+    clone:function (source, target) {
+        var tmp;
+        target = target || {};
+        for (var i in source) {
+            if (source.hasOwnProperty(i)) {
+                tmp = source[i];
+                if (typeof tmp == 'object') {
+                    target[i] = utils.isArray(tmp) ? [] : {};
+                    utils.clone(source[i], target[i])
+                } else {
+                    target[i] = tmp;
+                }
+            }
+        }
+        return target;
+    },
+    /**
+     * 转换cm/pt到px
+     * @name transUnitToPx
+     * @grammar UE.utils.transUnitToPx('20pt') => '27px'
+     * @grammar UE.utils.transUnitToPx('0pt') => '0'
+     */
+    transUnitToPx : function(val){
+        if(!/(pt|cm)/.test(val)){
+            return val
+        }
+        var unit;
+        val.replace(/([\d.]+)(\w+)/,function(str,v,u){
+            val = v;
+            unit = u;
+        });
+        switch(unit){
+            case 'cm':
+                val = parseFloat(val) * 25;
+                break;
+            case 'pt':
+                val = Math.round(parseFloat(val) * 96 / 72);
+        }
+        return val + (val?'px':'');
+    },
+    /**
+	 * 在targetElement后方插入元素
+	 * 
+	 * @param newElement
+	 * @param targerElement
+	 */
+	insertAfter : function(newElement, targetElement) {
+		var parent = targetElement.parentNode;
+		if (parent.lastChild == targetElement)
+		{
+			parent.appendChild(newElement);
+		} else {
+			parent.insertBefore(newElement, targetElement.nextSibling);
+		}
+	},
+    /**
+     * DomReady方法,回调函数将在dom树ready完成后执行
+     * @name domReady
+     * @grammar UE.utils.domReady(fn)  => fn  //返回一个延迟执行的方法
+     */
+    domReady:function () {
+
+        var fnArr = [];
+
+        function doReady(doc) {
+            //确保onready只执行一次
+            doc.isReady = true;
+            for (var ci; ci = fnArr.pop();ci()){}
+        }
+
+        return function (onready,win) {
+            win = win || window;
+            var doc = win.document;
+            onready && fnArr.push(onready);
+            if (doc.readyState === "complete") {
+                doReady(doc);
+            }else{
+                doc.isReady && doReady(doc);
+                if (browser.ie) {
+                    (function () {
+                        if (doc.isReady) return;
+                        try {
+                            doc.documentElement.doScroll("left");
+                        } catch (error) {
+                            setTimeout(arguments.callee, 0);
+                            return;
+                        }
+                        doReady(doc);
+                    })();
+                    win.attachEvent('onload', function(){
+                        doReady(doc)
+                    });
+                } else {
+                    doc.addEventListener("DOMContentLoaded", function () {
+                        doc.removeEventListener("DOMContentLoaded", arguments.callee, false);
+                        doReady(doc);
+                    }, false);
+                    win.addEventListener('load', function(){doReady(doc)}, false);
+                }
+            }
+
+        }
+    }(),
+    /**
+     * 动态添加css样式
+     * @name cssRule
+     * @grammar UE.utils.cssRule('添加的样式的节点名称',['样式','放到哪个document上'])
+     * @grammar UE.utils.cssRule('body','body{background:#ccc}') => null  //给body添加背景颜色
+     * @grammar UE.utils.cssRule('body') =>样式的字符串  //取得key值为body的样式的内容,如果没有找到key值先关的样式将返回空,例如刚才那个背景颜色,将返回 body{background:#ccc}
+     * @grammar UE.utils.cssRule('body','') =>null //清空给定的key值的背景颜色
+     */
+    cssRule : browser.ie ? function(key,style,doc){
+            var indexList,index;
+            doc = doc || document;
+            if(doc.indexList){
+                indexList = doc.indexList;
+            }else{
+                indexList = doc.indexList =  {};
+            }
+            var sheetStyle;
+            if(!indexList[key]){
+                if(style === undefined){
+                    return ''
+                }
+                sheetStyle = doc.createStyleSheet('',index = doc.styleSheets.length);
+                indexList[key] = index;
+            }else{
+                sheetStyle = doc.styleSheets[indexList[key]];
+            }
+            if(style === undefined){
+                return sheetStyle.cssText
+            }
+            sheetStyle.cssText = style || ''
+        }:function(key,style,doc){
+            doc = doc || document;
+            var head = doc.getElementsByTagName('head')[0],node;
+            if(!(node = doc.getElementById(key))){
+                if(style === undefined){
+                    return ''
+                }
+                node = doc.createElement('style');
+                node.id = key;
+                head.appendChild(node)
+            }
+            if(style === undefined){
+                return node.innerHTML
+            }
+            if(style !== ''){
+                node.innerHTML = style;
+            }else{
+                head.removeChild(node)
+            }
+        },
+        parseDomByString : function (str){
+    		var objE = document.createElement("div");
+    	   objE.innerHTML = str;
+    	   return objE.childNodes[0];
+    	}
+};
+/**
+ * 判断str是否为字符串
+ * @name isString
+ * @grammar UE.utils.isString(str) => true|false
+ */
+/**
+ * 判断array是否为数组
+ * @name isArray
+ * @grammar UE.utils.isArray(obj) => true|false
+ */
+/**
+ * 判断obj对象是否为方法
+ * @name isFunction
+ * @grammar UE.utils.isFunction(obj)  => true|false
+ */
+/**
+ * 判断obj对象是否为数字
+ * @name isNumber
+ * @grammar UE.utils.isNumber(obj)  => true|false
+ */
+utils.each(['String','Function','Array','Number','RegExp'],function(v){
+    UE.utils['is' + v] = function(obj){
+        return Object.prototype.toString.apply(obj) == '[object ' + v + ']';
+    }
+});

+ 151 - 0
web/js/ueditor2/_src/customEvent.js

@@ -0,0 +1,151 @@
+/**
+ * @file
+ * @name 编辑器事件接口
+ * @short Custom events
+ * @des 本文件非编辑器核心文件,仅适用于生成对应的事件接口文档
+ * UEditor编辑器中的所有事件监听和触发都统一采用
+ * ''editor''是编辑器实例
+ * editor.addListener("eventName",handler) 和 editor.fireEvent("eventName")方式调用,支持浏览器原生事件,如keydown,keyup,mousedown,mouseup等
+ */
+/**
+ * 编辑器加载完成事件(核心),在编辑器准备好所有运行条件时触发,大部分场景可以使用editor.ready(fn)取代。
+ * @name ready
+ * @grammar editor.addListener("ready",fn)
+ * @example
+ * editor.addListener("ready",function(){
+ *     //this为editor实例
+ *     this.setContent("欢迎使用UEditor!");
+ * })
+ * //同如下接口方式调用
+ * editor.ready(function(){
+ *     this.setContent("欢迎使用UEditor!");
+ * })
+ */
+/**
+ * 选区变化事件(核心),当选区出现变化时触发。
+ * 在UEditor中,任何涉及到光标改变的操作都会触发选区变化事件,该事件主要用来实现工具栏状态反射。
+ * @name selectionChange
+ * @grammar editor.addListener("selectionChange",fn)
+ * @grammar editor.fireEvent("selectionChange")
+ * @example
+ * editor.addListener("selectionChange",function(){
+ *     //this为editor实例
+ * })
+ */
+
+/**
+ * 内容变化事件(核心),当编辑区域中的文本内容出现变化时触发
+ * @name contentChange
+ * @grammar editor.addListener("contentChange",fn)
+ * @grammar editor.fireEvent("contentChange")
+ */
+
+/**
+ * 粘贴事件(核心),当使用ctr+v快捷键粘贴(包括Chrome、FF浏览器的右键粘贴)时会触发本事件
+ * @name (before|after)Paste
+ * @grammar editor.addListener("beforePaste",fn)
+ * @desc
+ * * beforePaste 在将粘贴的内容写到编辑器之前触发,这个事件触发时,粘贴的内容还未在编辑器内显示
+ * * afterPaste 粘贴的内容已经写到编辑器里边后触发
+ * @example
+ * editor.addListener("beforePaste",function(type,data){
+ *     //beforePaste事件监听区别于afterPaste事件监听最主要的一个方面是存在一个data参数,
+ *     //该data参数是一个对象,包含属性html。
+ *     //若用户在此处更改该html的值时,将会影响粘贴到编辑器中的内容,主要用于粘贴时需要特殊处理的一些场景。
+ *     console.log(this.getContent) //this都是当前编辑器的实例
+ *     //before事件才用这个参数,用来在写出编辑器之前对粘贴进来的内容进行最后的修改
+ *     data.html = "我把粘贴内容改成了这句话";
+ * })
+ */
+
+/**
+ * 设置内容事件(核心),当调用setContent方法时触发
+ * @name (before|after)SetContent
+ * @grammar editor.addListener("beforeSetContent",fn)
+ * @desc
+ * * beforeSetContent 在内容写到编辑器之前触发
+ * * afterSetContent 内容已经写到编辑器里边后触发
+ * @example
+ * editor.addListener("beforeSetContent",function(type,data){
+ *     //beforeSetContent事件监听区别于afterSetContent事件监听最主要的一个方面是存在一个data参数,
+ *     //该data参数是一个对象,包含属性html。
+ *     //若用户在此处更改该html的值时,将会影响设置到编辑器中的内容,主要用于设置内容时需要特殊处理的一些场景。
+ *     data.html = "我把设置内容改成了这句话";
+ * })
+ */
+
+/**
+ * getAllHtml事件,当调用getAllHtml方法时触发
+ * @name getAllHtml
+ * @grammar editor.addListener("getAllHtml",fn)
+ * @desc
+ * * 主要用来对于生成的整个html代码中的head内容进行定制,比如你想插入你自己的样式,script标签等,用来在展示时使用
+ * @example
+ * editor.addListener("getAllHtml",function(type,data){
+ *     //data是document中head部分html的封装,可通过data.html来获取对应字符串。
+ *     //需要修改的话得重新赋值data.html = '<style type="text/css"> body{margin:0;}</style>';
+ * })
+ */
+
+/**
+ * 内容提交事件(插件),当内容提交插件加载并调用了autosubmit命令时触发,多用于提交之前的验证
+ * @name beforeSubmit
+ * @grammar editor.addListener("beforeSubmit",fn)   //若fn返回false,则阻止本次提交
+ * @example
+ * editor.addListener("beforeSubmit",function(){
+ *     if(!editor.hasContents()){
+ *         return false;
+ *     }
+ * })
+ */
+
+/**
+ * 如果抓取远程的图片失败了,就触发
+ * @name catchRemoteError
+ * @grammar editor.addListener("catchRemoteError",fn)
+ * @example
+ * editor.addListener("catchRemoteError",function(){
+ *     console.log("抓取失败了!")
+ * })
+ */
+
+/**
+ * 当抓取远程的图片成功并会返回生成图片的链接时触发
+ * @name catchRemoterSuccess
+ * @grammar editor.addListener("catchRemoterSuccess",fn)
+ * @example
+ * editor.addListener("catchRemoterSuccess",function(){
+ *     console.log("抓取成功")
+ * })
+ */
+
+/**
+ * 编辑模式切换事件(插件),当源码模式和富文本模式发生切换时触发事件
+ * @name sourceModeChanged
+ * @grammar  editor.addListener("sourceModeChanged",fn)
+ * @example
+ * editor.addListener("sourceModeChanged",function(type,mode){
+ *     //mode代表了当前的编辑模式,true代表切换到了源码模式,false代表切换到了富文本模式
+ * })
+ */
+
+/**
+ * 全屏切换事件(插件),当执行全屏切换的时候触发事件
+ * @name fullScreenChanged
+ * @grammar  editor.addListener("fullScreenChanged",fn)
+ * @example
+ * editor.addListener("fullScreenChanged",function(type,mode){
+ *     //mode代表当前是否全屏,true代表切换到了全屏模式,false代表切换到了普通模式
+ * })
+ */
+
+/**
+ * 字数超出限制事件(插件),当输入的字符数超出配置项配置时触发
+ * @name wordCountOverflow
+ * @grammar editor.addListener("wordCountOverflow",fn)
+ * @example
+ * editor.addListener("wordCountOverflow",function(type,length){
+ *     console.log(length)
+ * })
+ */
+

+ 19 - 0
web/js/ueditor2/_src/editor.js

@@ -0,0 +1,19 @@
+UEDITOR_CONFIG = window.UEDITOR_CONFIG || {};
+
+var baidu = window.baidu || {};
+
+window.baidu = baidu;
+
+window.UE = baidu.editor =  {};
+
+UE.plugins = {};
+
+UE.commands = {};
+
+UE.instants = {};
+
+UE.I18N = {};
+
+UE.version = "1.2.5.0";
+
+var dom = UE.dom = {};

+ 42 - 0
web/js/ueditor2/_src/extend/ExtendConf.js

@@ -0,0 +1,42 @@
+/**
+ * ueditor扩展插件的配置
+ */
+var ExtendConf = UE.ExtendConf = {
+	iframeUrlMap: {
+		'input': '~/dialogs/extend/input/input.jsp',
+		'opinion': '~/dialogs/extend/opinion/opinion.jsp',
+		'insertfunction': '~/dialogs/extend/insertfunction/MathExpEditor.jsp',
+		'importform': '~/dialogs/extend/import/importform.jsp',
+		'customdialog': '~/dialogs/extend/dialog/dialog.jsp',
+		'customquery':'~/dialogs/extend/query/query.jsp',
+		'customquerydialog':'~/dialogs/extend/query/dialog.jsp',
+		'cascadequery':'~/dialogs/extend/query/queryMulVar.jsp',
+		'numbervalidate':'~/dialogs/extend/validate/number.jsp',
+		'daterangevalidate':'~/dialogs/extend/validate/daterange.jsp',
+		'international':'~/dialogs/extend/international/international.jsp',
+		'wordtemplate':'~/dialogs/extend/template/wordtemplate.jsp',
+		'datecalculate': '~/dialogs/extend/insertfunction/datecalculate.jsp',
+		'exportexceldialog': '~/dialogs/extend/exceltemp/exportexceldialog.jsp',
+		'importexceldialog': '~/dialogs/extend/exceltemp/importexceldialog.jsp',
+		
+		'input_mb': '~/dialogs/extend/input/input.jsp?type=mb',
+		'customdialog_mb': '~/dialogs/extend/dialog/dialog.jsp?type=mb',
+		'insertfunction_mb': '~/dialogs/extend/insertfunction/MathExpEditor.jsp?type=mb',
+		'daterangevalidate_mb':'~/dialogs/extend/validate/daterange.jsp?type=mb',
+		'datecalculate_mb': '~/dialogs/extend/insertfunction/datecalculate.jsp?type=mb',
+		'numbervalidate_mb':'~/dialogs/extend/validate/number.jsp?type=mb'
+	},
+
+	btnCmds:['tableformat','choosetemplate','opinion','input','taskopinion','flowchart',
+	         'insertfunction','cutsubtable','pastesubtable','customdialog','clearcell',
+	         'insertrownext','insertcolnext','customquery','uncustomquery','numbervalidate','daterangevalidate','datecalculate','international','serialnum',
+	         'hidedomain','textinput','textarea','checkbox','radioinput','selectinput',
+             'dictionary','personpicker','departmentpicker','datepicker','officecontrol','subtable',
+             'myeditor','rolepicker','positionpicker','attachement','onlinetext','importform','exportform','pasteinput','cascadequery','wordtemplate','exportexceldialog','importexceldialog',
+             'input_mb','insertfunction_mb','daterangevalidate_mb','datecalculate_mb','numbervalidate_mb','customdialog_mb','choosetemplate_mb',
+             'sendperson','readperson','jumpurl' ,'taskname','htmldefform','textdefform','remaintime','signset',
+             'subject','startuser', 'startdate','starttime','businesskey'],
+ 
+	dialogBtns: ['importform', 'customquery','customquerydialog','cascadequery','opinion','customdialog','input','insertfunction','numbervalidate','daterangevalidate','datecalculate','international','uncascadequery','setreadonly','delreadonly','wordtemplate','exportexceldialog','importexceldialog',
+	             'input_mb','insertfunction_mb','daterangevalidate_mb','datecalculate_mb','numbervalidate_mb','customdialog_mb']
+}

+ 63 - 0
web/js/ueditor2/_src/extend/plugins/cascadequery.js

@@ -0,0 +1,63 @@
+
+/**
+ * 级联设置
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="customdialog"
+ */
+UE.commands['cascadequery'] = {	
+	execCommand : function(cmdName) {
+		var me=this;
+		
+		if(!me.ui._dialogs['cascadequeryDialog']){
+			baidu.editor.ui['cascadequery'](me);
+		}
+		me.ui._dialogs['cascadequeryDialog'].open();
+	},
+	queryCommandState : function() {
+		return 0;
+	}
+}
+/**
+ * 删除级联
+ * @type 
+ */
+UE.commands['uncascadequery'] = {	
+	execCommand : function(cmdName) {
+		var node = this.curInput;
+		if(node && "SELECT"==node.nodeName.toUpperCase()){
+			node = getRealObj(node);
+			node.removeAttribute("selectquery");
+		}
+	},
+	queryCommandState : function() {
+			return 0;
+	}
+};
+/**
+ * 查找实际存放 自定义查询 数据的标签元素
+ * @param obj
+ * @returns
+ */
+function getRealObj(obj){
+	var curNode = obj;
+	var selectId;
+	var fieldName=obj.getAttribute("name");
+	var parent=obj.parentNode;
+	if(fieldName && parent){
+		var idFieldName=fieldName+"ID";
+		var tmp = parent.getElementsByTagName("select");
+		if(tmp!=null){
+			for(var i=0;i<tmp.length;i++){
+				if(idFieldName == tmp[i].getAttribute("name")){
+					selectId = tmp[i];
+					break;
+				}
+			}
+		}
+		if(selectId){
+			curNode=selectId;
+		}
+	}
+	return curNode;
+};

+ 43 - 0
web/js/ueditor2/_src/extend/plugins/choosetemplate.js

@@ -0,0 +1,43 @@
+///import core
+///import plugins\addinput.js
+///commands 添加按钮
+///commandsName  addinput
+///commandsTitle  添加按钮
+/**
+ * @description 添加按钮(按钮、单选按钮、复选框、单行文本、多行文本、列表菜单等)
+ * @name baidu.editor.execCommand
+ * @param {String}
+ *            cmdName 添加按钮
+ * @author heyifan
+ */
+UE.plugins['choosetemplate'] = function() {
+	var me = this;
+	me.commands['choosetemplate'] = {
+		execCommand : function(cmdName) {
+			//编辑器设计表单模式
+			if(typeof FormDef == 'undefined' || typeof tableId  == 'undefined'){
+				//重新选择模板(该方法的定义在bpmFormDefDesignEdit.jsp页面)
+				showSelectTemplate(__ctx+'/platform/form/bpmFormDef/chooseDesignTemplate.ht?&isSimple=1');	
+			}
+			else{
+				FormDef.showSelectTemplate(__ctx+'/platform/form/bpmFormDef/selectTemplate.ht?tableId=' + tableId +"&isSimple=1");
+			}
+		},
+		queryCommandState : function() {
+			return this.highlight ? -1 : 0;
+		}
+	};	
+};
+
+UE.plugins['choosetemplate_mb'] = function() {
+	var me = this;
+	me.commands['choosetemplate_mb'] = {
+		execCommand : function(cmdName) {
+			//编辑器设计表单模式
+			FormDef.selectTemplate(editor);
+		},
+		queryCommandState : function() {
+			return this.highlight ? -1 : 0;
+		}
+	};	
+};

+ 32 - 0
web/js/ueditor2/_src/extend/plugins/customdialog.js

@@ -0,0 +1,32 @@
+/**
+ * 自定义对话框
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="customdialog"
+ */
+UE.commands['customdialog'] = {	
+	execCommand : function(cmdName) {
+		var me=this;
+		
+		if(!me.ui._dialogs['customdialogDialog']){
+			baidu.editor.ui['customdialog'](me);
+		}
+		me.ui._dialogs['customdialogDialog'].open();
+	},
+	queryCommandState : function() {
+		return 0;
+	}
+}
+
+UE.commands['customdialog_mb'] = {
+		execCommand : function(cmdName) {
+			var me=this;
+			if(!me.ui._dialogs['customdialog_mbDialog']){
+				baidu.editor.ui['customdialog_mb'](me);
+			}
+			me.ui._dialogs['customdialog_mbDialog'].open();
+		},
+		queryCommandState : function() {
+			return 0;
+		}
+	}

+ 98 - 0
web/js/ueditor2/_src/extend/plugins/customquery.js

@@ -0,0 +1,98 @@
+/**
+ * 联动设置
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="customquery"
+ */
+UE.commands['customquery'] = {	
+	
+	execCommand : function(cmdName) {
+		
+	},
+	queryCommandState : function(cmdName) {
+		var node = this.selection.getStart();
+		if(node && "INPUT"==node.nodeName.toUpperCase()){
+			node = __getRealObj(node);
+			this.curQuery=node;
+			var query = node.getAttribute("query");
+			if(query){
+				return 1;
+			}else{
+				return 0;
+			}
+		}else{
+			return -1;
+		}
+	}
+};
+UE.commands['uncustomquery'] = {	
+	execCommand : function(cmdName) {
+		var node = this.selection.getStart();
+		if(node && "INPUT"==node.nodeName.toUpperCase()){
+			node = __getRealObj(node);
+			node.removeAttribute("query");
+		}
+	},
+	queryCommandState : function(cmdName) {
+		var node = this.selection.getStart();
+		if(node && "INPUT"==node.nodeName.toUpperCase()){
+			node = __getRealObj(node);
+			var query = "";//node.getAttribute("query");
+			if(query){
+				return 0;
+			}else{
+				return -1;
+			}
+		}else{
+			return -1;
+		}
+	}
+};
+
+/**
+ * 联动设置
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="customquery"
+ */
+UE.commands['customquerydialog'] = {
+	
+	execCommand : function(cmdName) {
+		var me=this;
+		
+		if(!me.ui._dialogs['customquerydialogDialog']){
+			baidu.editor.ui['customquerydialog'](me);
+		}
+		me.ui._dialogs['customquerydialogDialog'].open();
+	},
+	queryCommandState : function() {
+		return 0;
+	}
+};
+/**
+ * 查找实际存放 自定义查询 数据的标签元素
+ * @param obj
+ * @returns
+ */
+function __getRealObj(obj){
+	var curNode = obj;
+	var inputId;
+	var fieldName=obj.getAttribute("name");
+	var parent=obj.parentNode;
+	if(fieldName && parent){
+		var idFieldName=fieldName+"ID";
+		var tmp = parent.getElementsByTagName("input");
+		if(tmp!=null){
+			for(var i=0;i<tmp.length;i++){
+				if(idFieldName == tmp[i].getAttribute("name")){
+					inputId = tmp[i];
+					break;
+				}
+			}
+		}
+		if(inputId){
+			curNode=inputId;
+		}
+	}
+	return curNode;
+};

+ 53 - 0
web/js/ueditor2/_src/extend/plugins/datecalculate.js

@@ -0,0 +1,53 @@
+/**
+ * 日期计算
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="datecalculate"
+ */
+var datecalculate ={
+	execCommand : function(cmdName) {
+		
+	},
+	queryCommandState : function() {
+		var node = this.selection.getStart();
+		if(editor.isMoble_){
+			if(node.hasAttribute("ht-date")) return -1
+		}
+		
+		if(node && "INPUT"==node.nodeName.toUpperCase()){
+		   var flag	 = getRealObj(node);
+			if(node)
+				return 0;
+			else
+				return -1;
+		}
+		else
+			return -1;
+	}
+}
+UE.commands['datecalculate'] = datecalculate;
+UE.commands['datecalculate_mb'] = datecalculate;
+/**
+ * 查找实际存放 自定义查询 数据的标签元素
+ * @param obj
+ * @returns
+ */
+function getRealObj(obj){
+	var fieldName=obj.getAttribute("name");
+	var parent=obj.parentNode;
+	if(fieldName){
+		 if(obj && "WDATE"==obj.className.toUpperCase()){
+			 return true ;
+		 }else{
+			 return false ;
+		 }
+	}
+	if(parent){
+		 if(parent && "DATEPICKER"==parent.className.toUpperCase()){
+			 return true ;
+		 }else{
+			 return false ;
+		 }
+	}
+	return false;
+};

+ 54 - 0
web/js/ueditor2/_src/extend/plugins/daterangevalidate.js

@@ -0,0 +1,54 @@
+/**
+ * 字段日期范围验证
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="daterangevalidate"
+ */
+UE.commands['daterangevalidate'] = {	
+	execCommand : function(cmdName) {
+		
+	},
+	queryCommandState : function() {
+		var node = this.selection.getStart();
+		
+		if(editor.isMoble_){
+			if(node.hasAttribute("ht-date")) return 0
+			else return -1;
+		}
+		
+		if(node && "INPUT"==node.nodeName.toUpperCase()){
+		   var flag	 = getRealObj(node);
+			if(node)
+				return 0;
+			else
+				return -1;
+		}
+		else
+			return -1;
+	}
+}
+
+/**
+ * 查找实际存放 自定义查询 数据的标签元素
+ * @param obj
+ * @returns
+ */
+function getRealObj(obj){
+	var fieldName=obj.getAttribute("name");
+	var parent=obj.parentNode;
+	if(fieldName ){
+		 if(obj && "WDATE"==obj.className.toUpperCase()){
+			 return true ;
+		 }else{
+			 return false ;
+		 }
+	}
+	if(parent){
+		 if(parent && "DATEPICKER"==parent.className.toUpperCase()){
+			 return true ;
+		 }else{
+			 return false ;
+		 }
+	}
+	return false;
+};

+ 19 - 0
web/js/ueditor2/_src/extend/plugins/exportexceldialog.js

@@ -0,0 +1,19 @@
+/**
+ * 导出Excel的自定义对话框
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="exportexceldialog"
+ */
+UE.commands['exportexceldialog'] = {	
+	execCommand : function(cmdName) {
+		var me=this;
+		
+		if(!me.ui._dialogs['exportexceldialogDialog']){
+			baidu.editor.ui['exportexceldialog'](me);
+		}
+		me.ui._dialogs['exportexceldialogDialog'].open();
+	},
+	queryCommandState : function() {
+		return 0;
+	}
+}

+ 17 - 0
web/js/ueditor2/_src/extend/plugins/exportform.js

@@ -0,0 +1,17 @@
+/**
+ * 导出表单
+ * 
+ * @function
+ * @name baidu.editor.execCommands
+ * @param {String}
+ *            cmdName cmdName="exportform"导入表单
+ */
+
+UE.commands['exportform'] = {
+	execCommand : function(cmd, name) {
+		exportform();
+	},
+	queryCommandState : function() {
+		return this.highlight ? -1 : 0;
+	}
+};

+ 11 - 0
web/js/ueditor2/_src/extend/plugins/flowchart.js

@@ -0,0 +1,11 @@
+UE.commands['flowchart'] = {
+    execCommand:function (cmd) {
+    	var me = this;
+    	var html=' <div name="editable-input" class="flowchart"><input type="text" /></div>';
+        me.execCommand('insertHtml',html);
+    },
+    queryCommandState:function () {
+        return this.highlight ? -1 : 0;
+    }
+};
+

+ 19 - 0
web/js/ueditor2/_src/extend/plugins/importexceldialog.js

@@ -0,0 +1,19 @@
+/**
+ * 导入Excel的自定义对话框
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="importexceldialog"
+ */
+UE.commands['importexceldialog'] = {	
+	execCommand : function(cmdName) {
+		var me=this;
+		
+		if(!me.ui._dialogs['importexceldialogDialog']){
+			baidu.editor.ui['importexceldialog'](me);
+		}
+		me.ui._dialogs['importexceldialogDialog'].open();
+	},
+	queryCommandState : function() {
+		return 0;
+	}
+}

+ 16 - 0
web/js/ueditor2/_src/extend/plugins/importform.js

@@ -0,0 +1,16 @@
+/**
+ * 导入表单
+ * 
+ * @function
+ * @name baidu.editor.execCommands
+ * @param {String}
+ *            cmdName cmdName="importform"导入表单
+ */
+
+UE.commands['importform'] = {
+	execCommand : function(cmd, name) {
+	},
+	queryCommandState : function() {
+		return this.highlight ? -1 : 0;
+	}
+};

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1322 - 0
web/js/ueditor2/_src/extend/plugins/input.js


+ 29 - 0
web/js/ueditor2/_src/extend/plugins/international.js

@@ -0,0 +1,29 @@
+/**
+ * 提取国际化资源
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="international"
+ */
+UE.commands['international'] = {
+	execCommand : function(cmdName) {
+	},
+	queryCommandState : function() {
+		if(this.highlight)
+			return -1;
+		var range = this.selection.getRange(),
+        	text = this.selection.getText();
+		
+		if(!text)return -1;
+		var curNode =  range.startContainer;
+		if(range.startContainer.nodeType!=3 )
+			return -1;
+		var parent = domUtils.findParents(curNode,false,null,true)[0];
+		if(!parent)return -1;
+		var alreadySet = (parent.tagName=='SPAN'&&parent.getAttribute("i18nkey")); 
+		if(alreadySet)return -1;
+		else{
+			this.$curTextNode = curNode;
+			return 0;
+		}
+	}
+}

+ 39 - 0
web/js/ueditor2/_src/extend/plugins/mathfunction.js

@@ -0,0 +1,39 @@
+/**
+ * 统计函数
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="insertfunction"
+ */
+UE.commands['insertfunction'] = {	
+	execCommand : function(cmdName) {
+		return;
+	},
+	queryCommandState : function() {
+		var range = this.selection.getRange();
+        var el = range.getClosedNode();
+        if(!el&&range){
+            var startContainer = range.startContainer;
+            if(startContainer &&  ('TD' == startContainer.nodeName.toUpperCase() || 'SPAN' == startContainer.nodeName.toUpperCase())){
+                el = startContainer.childNodes[range.startOffset];
+            }
+        }
+		return el ? 0 : -1;
+	}
+}
+
+UE.commands['insertfunction_mb'] = {	
+		execCommand : function(cmdName) {
+		},
+		queryCommandState : function() {
+			var node = this.selection.getStart();
+			if(node && "INPUT"==node.nodeName.toUpperCase()){
+			   var flag	 = getRealObj(node);
+				if(node)
+					return 0;
+				else
+					return -1;
+			}
+			else
+				return -1;
+		}
+	}

+ 26 - 0
web/js/ueditor2/_src/extend/plugins/numbervalidate.js

@@ -0,0 +1,26 @@
+/**
+ * 字段验证
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="numbervalidate"
+ */
+UE.commands['numbervalidate'] = {	
+	execCommand : function(cmdName) {
+		
+	},
+	queryCommandState : function() {
+		
+		var node = this.selection.getStart();
+		
+		if(node && "INPUT"==node.nodeName.toUpperCase()){
+			var valid=node.getAttribute("validate")
+			if(valid){
+				var validObj=eval("(" + valid +")");
+				if(validObj && validObj.number){
+					return 0;
+				}
+			}
+		}
+		return -1;
+	}
+}

+ 42 - 0
web/js/ueditor2/_src/extend/plugins/opinion.js

@@ -0,0 +1,42 @@
+///import core
+///import plugins\opinion.js
+///commands 意见框
+///commandsName  opinion
+///commandsTitle  意见框
+/**
+ * @description 意见框
+ * @name baidu.editor.execCommand
+ * @param {String}
+ *            cmdName 意见框
+ * @author heyifan
+ */
+UE.plugins['opinion'] = function() {
+	var me = this;
+	me.commands['addopinion'] = {
+		execCommand : function(cmdName) {
+			me.curOpinion=null;
+			this.ui._dialogs['opinionDialog'].open({height:'200px'});
+			return true;
+		},
+		queryCommandState : function() {
+			return this.highlight ? -1 : 0;
+		}
+	};
+	me.commands['editopinion'] = {
+		execCommand : function(cmdName) {
+			me.curOpinion=this.selection.getRange().getClosedNode();
+			this.ui._dialogs['opinionDialog'].open();
+			return true;
+		},
+		queryCommandState : function() {
+			 var el = this.selection.getRange().getClosedNode();
+			 if(!el){
+				 return -1;
+			 }
+			 else if(el.tagName.toLowerCase()=='input'||el.tagName.toLowerCase()=='textarea'||el.tagName.toLowerCase()=='select'){
+				 return this.highlight ? -1 : 0;
+			 }
+			 return -1;
+		}
+	};
+};

+ 24 - 0
web/js/ueditor2/_src/extend/plugins/pasteinput.js

@@ -0,0 +1,24 @@
+/**
+ * 粘贴字段
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="pasteinput"
+ */
+UE.commands['pasteinput'] = {	
+	execCommand : function(cmdName) {
+		var start = this.selection.getStart();
+		if(!start||!editor.curCutInput)return;
+		if(start.tagName=='TD'){
+			start.appendChild(editor.curCutInput);
+		}
+		else{
+			start = domUtils.findEditableInput(start);
+			utils.insertAfter(editor.curCutInput, start);
+		}
+		editor.curCutInput = null;
+	},
+	queryCommandState : function() {
+		if(this.highlight||!editor.curCutInput){return -1;}
+		return 0;
+	}
+}

+ 16 - 0
web/js/ueditor2/_src/extend/plugins/serialnum.js

@@ -0,0 +1,16 @@
+/**
+ * 添加流水号
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="serialnum"
+ */
+UE.commands['serialnum'] = {	
+	execCommand : function(cmdName) {
+		var me = this;
+		var html='<span name="editable-input" class="onlydelete" serialnum="true">流水号</span>';
+	    me.execCommand('insertHtml',html);
+	},
+	queryCommandState : function() {
+		 return this.highlight ? -1 : 0;
+	}
+}

+ 79 - 0
web/js/ueditor2/_src/extend/plugins/setreadonly.js

@@ -0,0 +1,79 @@
+/**
+ * 设置只读
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="setreadonly"
+ */
+UE.commands['setreadonly'] = {	
+	execCommand : function(cmdName) {
+		var node = this.curInput;
+		if(node && ("SELECT"==node.nodeName.toUpperCase()||"INPUT"==node.nodeName.toUpperCase()||"TEXTAREA"==node.nodeName.toUpperCase())){
+			node = __getRealObj(node);
+			node.setAttribute("readonly","readonly");
+		}
+	},
+	queryCommandState : function() {
+		return 0;
+	}
+}
+/**
+ * 删除只读
+ * @type 
+ */
+UE.commands['delreadonly'] = {	
+	execCommand : function(cmdName) {
+		var node = this.curInput;
+		if(node && ("SELECT"==node.nodeName.toUpperCase()||"INPUT"==node.nodeName.toUpperCase()||"TEXTAREA"==node.nodeName.toUpperCase())){
+			node = __getRealObj(node);
+			node.removeAttribute("readonly");
+		}
+	},
+	queryCommandState : function() {
+			return 0;
+	}
+};
+/**
+ * 查找实际存放 自定义查询 数据的标签元素
+ * @param obj
+ * @returns
+ */
+function __getRealObj(obj){
+	var curNode = obj;
+	var Id;
+	var fieldName=obj.getAttribute("name");
+	var parent=obj.parentNode;
+	if(fieldName && parent){
+		var idFieldName=fieldName+"ID";
+		var inputtmp = parent.getElementsByTagName("input");
+		var selecttmp= parent.getElementsByTagName("select");
+		var textareatmp= parent.getElementsByTagName("textarea");
+		if(inputtmp!=null){
+			for(var i=0;i<inputtmp.length;i++){
+				if(idFieldName == inputtmp[i].getAttribute("name")){
+					Id = inputtmp[i];
+					break;
+				}
+			}
+		}
+		if(selecttmp!=null){
+			for(var i=0;i<selecttmp.length;i++){
+				if(idFieldName == selecttmp[i].getAttribute("name")){
+					Id = selecttmp[i];
+					break;
+				}
+			}
+		}
+		if(textareatmp!=null){
+			for(var i=0;i<textareatmp.length;i++){
+				if(idFieldName == textareatmp[i].getAttribute("name")){
+					Id = textareatmp[i];
+					break;
+				}
+			}
+		}
+		if(Id){
+			curNode=Id;
+		}
+	}
+	return curNode;
+};

+ 55 - 0
web/js/ueditor2/_src/extend/plugins/subtable.js

@@ -0,0 +1,55 @@
+/**
+ * 子表操作
+ */
+UE.plugins['subtable'] = function() {
+	var me = this,
+		keys = domUtils.keys,
+		addClass = domUtils.addClass,
+		removeClass = domUtils.removeClass;
+
+	var tempDiv = null,
+		subTableDiv = null;
+
+	/**
+	 * 剪切子表
+	 */
+	me.commands['cutsubtable'] = {
+		queryCommandState: function(){
+			if(this.highlight ){return -1;}
+			var start = me.selection.getStart(),
+				div = domUtils.findParentByTagName(start,'div',true);
+			if(!div)return -1;
+			if(div.className=='subTableToolBar')
+				div = domUtils.findParentByTagName(div,'div',false);
+			if(div.getAttribute("type")!='subtable')return -1;
+			tempDiv = div;
+			return 0;
+		},
+		execCommand: function(cmdName, opt){
+			if(!tempDiv)return;
+			subTableDiv = tempDiv;
+			domUtils.remove(subTableDiv);
+		}
+	};
+
+	/**
+	 * 粘贴子表
+	 */
+	me.commands['pastesubtable'] = {
+		queryCommandState: function() {
+			if(this.highlight||!subTableDiv){return -1;}
+			return 0;
+		},
+		execCommand: function(cmdName, opt) {
+			var start = me.selection.getStart();
+			if(!start||!subTableDiv)return;
+			if(start.tagName=='TD'){
+				start.appendChild(subTableDiv);
+			}
+			else{
+				utils.insertAfter(subTableDiv, start);
+			}
+			subTableDiv = null;
+		}
+	};
+};

+ 11 - 0
web/js/ueditor2/_src/extend/plugins/taskopinion.js

@@ -0,0 +1,11 @@
+UE.commands['taskopinion'] = {
+    execCommand:function (cmd) {
+    	var me = this;
+    	var html='<div name="editable-input" class="taskopinion" instanceId="#instanceId#"><input type="text" /></div>';
+        me.execCommand('insertHtml',html);
+    },
+    queryCommandState:function () {
+        return this.highlight ? -1 : 0;
+    }
+};
+

+ 20 - 0
web/js/ueditor2/_src/extend/plugins/wordtemplate.js

@@ -0,0 +1,20 @@
+/**
+ * @description word套打模板
+ * @name baidu.editor.execCommand
+ * @param {String}
+ *            cmdName wordtemplate
+ * @author guojh
+ */
+UE.commands['wordtemplate'] = {
+	execCommand : function(cmdName) {
+		var me=this;
+		
+		if(!me.ui._dialogs['wordtemplateDialog']){
+			baidu.editor.ui['wordtemplate'](me);
+		}
+		me.ui._dialogs['wordtemplateDialog'].open();
+	},
+	queryCommandState : function() {
+		return 0;
+	}
+};

+ 47 - 0
web/js/ueditor2/_src/plugins/anchor.js

@@ -0,0 +1,47 @@
+///import core
+///commands 锚点
+///commandsName  Anchor
+///commandsTitle  锚点
+///commandsDialog  dialogs\anchor
+/**
+ * 锚点
+ * @function
+ * @name baidu.editor.execCommands
+ * @param {String} cmdName     cmdName="anchor"插入锚点
+ */
+UE.plugins['anchor'] = function (){
+    var me = this;
+
+    me.ready(function(){
+        utils.cssRule('anchor',
+            '.anchorclass{background: url(\'' + me.options.UEDITOR_HOME_URL + 'themes/default/images/anchor.gif\') no-repeat scroll left center transparent;border: 1px dotted #0000FF;cursor: auto;display: inline-block;height: 16px;width: 15px;}',me.document)
+    });
+
+    me.commands['anchor'] = {
+        execCommand:function (cmd, name) {
+            var range = this.selection.getRange(),img = range.getClosedNode();
+            if (img && img.getAttribute('anchorname')) {
+                if (name) {
+                    img.setAttribute('anchorname', name);
+                } else {
+                    range.setStartBefore(img).setCursor();
+                    domUtils.remove(img);
+                }
+            } else {
+                if (name) {
+                    //只在选区的开始插入
+                    var anchor = this.document.createElement('img');
+                    range.collapse(true);
+                    domUtils.setAttributes(anchor,{
+                        'anchorname':name,
+                        'class':'anchorclass'
+                    });
+                    range.insertNode(anchor).setStartAfter(anchor).setCursor(false,true);
+                }
+            }
+        }
+
+    };
+
+
+};

+ 131 - 0
web/js/ueditor2/_src/plugins/autofloat.js

@@ -0,0 +1,131 @@
+///import core
+///commands 悬浮工具栏
+///commandsName  AutoFloat,autoFloatEnabled
+///commandsTitle  悬浮工具栏
+/*
+ *  modified by chengchao01
+ *
+ *  注意: 引入此功能后,在IE6下会将body的背景图片覆盖掉!
+ */
+    UE.plugins['autofloat'] = function() {
+        var me = this,
+                lang = me.getLang();
+        me.setOpt({
+            topOffset:0
+        });
+        var optsAutoFloatEnabled = me.options.autoFloatEnabled !== false,
+        topOffset = me.options.topOffset;
+
+
+        //如果不固定toolbar的位置,则直接退出
+        if(!optsAutoFloatEnabled){
+            return;
+        }
+        var uiUtils = UE.ui.uiUtils,
+       		LteIE6 = browser.ie && browser.version <= 6,
+            quirks = browser.quirks;
+
+        function checkHasUI(editor){
+           if(!editor.ui){
+              alert(lang.autofloatMsg);
+               return 0;
+           }
+           return 1;
+       }
+        function fixIE6FixedPos(){
+            var docStyle = document.body.style;
+           docStyle.backgroundImage = 'url("about:blank")';
+           docStyle.backgroundAttachment = 'fixed';
+        }
+		var	bakCssText,
+			placeHolder = document.createElement('div'),
+            toolbarBox,orgTop,
+            getPosition,
+            flag =true;   //ie7模式下需要偏移
+		function setFloating(){
+			var toobarBoxPos = domUtils.getXY(toolbarBox),
+				origalFloat = domUtils.getComputedStyle(toolbarBox,'position'),
+                origalLeft = domUtils.getComputedStyle(toolbarBox,'left');
+			toolbarBox.style.width = toolbarBox.offsetWidth + 'px';
+            toolbarBox.style.zIndex = me.options.zIndex * 1 + 1;
+			toolbarBox.parentNode.insertBefore(placeHolder, toolbarBox);
+			if (LteIE6 || (quirks && browser.ie)) {
+                if(toolbarBox.style.position != 'absolute'){
+                    toolbarBox.style.position = 'absolute';
+                }
+                toolbarBox.style.top = (document.body.scrollTop||document.documentElement.scrollTop) - orgTop + topOffset  + 'px';
+			} else {
+                if (browser.ie7Compat && flag) {
+                    flag = false;
+                    toolbarBox.style.left =  domUtils.getXY(toolbarBox).x - document.documentElement.getBoundingClientRect().left+2  + 'px';
+                }
+                if(toolbarBox.style.position != 'fixed'){
+                    toolbarBox.style.position = 'fixed';
+                    toolbarBox.style.top = topOffset +"px";
+                    ((origalFloat == 'absolute' || origalFloat == 'relative') && parseFloat(origalLeft)) && (toolbarBox.style.left = toobarBoxPos.x + 'px');
+                }
+			}
+		}
+		function unsetFloating(){
+            flag = true;
+            if(placeHolder.parentNode){
+                placeHolder.parentNode.removeChild(placeHolder);
+            }
+			toolbarBox.style.cssText = bakCssText;
+		}
+
+        function updateFloating(){
+            var rect3 = getPosition(me.container);
+            if (rect3.top < 0 && rect3.bottom - toolbarBox.offsetHeight > 0) {
+                setFloating();
+            }else{
+                unsetFloating();
+            }
+        }
+        var defer_updateFloating = utils.defer(function(){
+            updateFloating();
+        },browser.ie ? 200 : 100,true);
+
+        me.addListener('destroy',function(){
+            domUtils.un(window, ['scroll','resize'], updateFloating);
+            me.removeListener('keydown', defer_updateFloating);
+        });
+
+        me.addListener('ready', function(){
+            if(checkHasUI(me)){
+
+                getPosition = uiUtils.getClientRect;
+                toolbarBox = me.ui.getDom('toolbarbox');
+                orgTop = getPosition(toolbarBox).top;
+                bakCssText = toolbarBox.style.cssText;
+                placeHolder.style.height = toolbarBox.offsetHeight + 'px';
+                if(LteIE6){
+                    fixIE6FixedPos();
+                }
+                domUtils.on(window, ['scroll','resize'], updateFloating);
+                me.addListener('keydown', defer_updateFloating);
+
+                me.addListener('beforefullscreenchange', function (t, enabled){
+                    if (enabled) {
+                        unsetFloating();
+                    }
+                });
+                me.addListener('fullscreenchanged', function (t, enabled){
+                    if (!enabled) {
+                        updateFloating();
+                    }
+                });
+                me.addListener('sourcemodechanged', function (t, enabled){
+                    setTimeout(function (){
+                        updateFloating();
+                    },0);
+                });
+                me.addListener("clearDoc",function(){
+                    setTimeout(function(){
+                        updateFloating();
+                    },0);
+
+                })
+            }
+        });
+	};

+ 107 - 0
web/js/ueditor2/_src/plugins/autoheight.js

@@ -0,0 +1,107 @@
+///import core
+///commands 当输入内容超过编辑器高度时,编辑器自动增高
+///commandsName  AutoHeight,autoHeightEnabled
+///commandsTitle  自动增高
+/**
+ * @description 自动伸展
+ * @author zhanyi
+ */
+UE.plugins['autoheight'] = function () {
+    var me = this;
+    //提供开关,就算加载也可以关闭
+    me.autoHeightEnabled = me.options.autoHeightEnabled !== false;
+    if (!me.autoHeightEnabled) {
+        return;
+    }
+
+    var bakOverflow,
+        span, tmpNode,
+        lastHeight = 0,
+        options = me.options,
+        currentHeight,
+        timer;
+
+    function adjustHeight() {
+        var me = this;
+        clearTimeout(timer);
+        if(isFullscreen)return;
+        timer = setTimeout(function () {
+
+            if (me.queryCommandState && me.queryCommandState('source') != 1) {
+                if (!span) {
+                    span = me.document.createElement('span');
+                    //trace:1764
+                    span.style.cssText = 'display:block;width:0;margin:0;padding:0;border:0;clear:both;';
+                    span.innerHTML = '.';
+                }
+                tmpNode = span.cloneNode(true);
+                me.body.appendChild(tmpNode);
+
+                currentHeight = Math.max(domUtils.getXY(tmpNode).y + tmpNode.offsetHeight,Math.max(options.minFrameHeight, options.initialFrameHeight));
+
+                if (currentHeight != lastHeight) {
+
+                    me.setHeight(currentHeight);
+
+                    lastHeight = currentHeight;
+                }
+
+                domUtils.remove(tmpNode);
+
+            }
+        }, 50);
+    }
+    var isFullscreen;
+    me.addListener('fullscreenchanged',function(cmd,f){
+        isFullscreen = f
+    });
+    me.addListener('destroy', function () {
+        me.removeListener('contentchange', adjustHeight);
+        me.removeListener('afterinserthtml',adjustHeight);
+        me.removeListener('keyup', adjustHeight);
+        me.removeListener('mouseup', adjustHeight);
+    });
+    me.enableAutoHeight = function () {
+        if (!me.autoHeightEnabled) {
+            return;
+        }
+        var doc = me.document;
+        me.autoHeightEnabled = true;
+        bakOverflow = doc.body.style.overflowY;
+        doc.body.style.overflowY = 'hidden';
+        me.addListener('contentchange', adjustHeight);
+        me.addListener('afterinserthtml',adjustHeight)
+        me.addListener('keyup', adjustHeight);
+        me.addListener('mouseup', adjustHeight);
+        //ff不给事件算得不对
+        setTimeout(function () {
+            adjustHeight.call(this);
+        }, browser.gecko ? 100 : 0);
+        me.fireEvent('autoheightchanged', me.autoHeightEnabled);
+    };
+    me.disableAutoHeight = function () {
+
+        me.body.style.overflowY = bakOverflow || '';
+
+        me.removeListener('contentchange', adjustHeight);
+        me.removeListener('keyup', adjustHeight);
+        me.removeListener('mouseup', adjustHeight);
+        me.autoHeightEnabled = false;
+        me.fireEvent('autoheightchanged', me.autoHeightEnabled);
+    };
+    me.addListener('ready', function () {
+        me.enableAutoHeight();
+        //trace:1764
+        var timer;
+        domUtils.on(browser.ie ? me.body : me.document, browser.webkit ? 'dragover' : 'drop', function () {
+            clearTimeout(timer);
+            timer = setTimeout(function () {
+                adjustHeight.call(this);
+            }, 100);
+
+        });
+    });
+
+
+};
+

+ 104 - 0
web/js/ueditor2/_src/plugins/autolink.js

@@ -0,0 +1,104 @@
+///import core
+///commands 为非ie浏览器自动添加a标签
+///commandsName  AutoLink
+///commandsTitle  自动增加链接
+/**
+ * @description 为非ie浏览器自动添加a标签
+ * @author zhanyi
+ */
+    UE.plugins['autolink'] = function() {
+        var cont = 0;
+        if (browser.ie) {
+            return;
+        }
+        var me = this;
+        me.addListener('reset',function(){
+           cont = 0;
+        });
+        me.addListener('keydown', function(type, evt) {
+            var keyCode = evt.keyCode || evt.which;
+
+            if (keyCode == 32 || keyCode == 13) {
+
+                var sel = me.selection.getNative(),
+                    range = sel.getRangeAt(0).cloneRange(),
+                    offset,
+                    charCode;
+
+                var start = range.startContainer;
+                while (start.nodeType == 1 && range.startOffset > 0) {
+                    start = range.startContainer.childNodes[range.startOffset - 1];
+                    if (!start){
+                        break;
+                    }
+                    range.setStart(start, start.nodeType == 1 ? start.childNodes.length : start.nodeValue.length);
+                    range.collapse(true);
+                    start = range.startContainer;
+                }
+
+                do{
+                    if (range.startOffset == 0) {
+                        start = range.startContainer.previousSibling;
+
+                        while (start && start.nodeType == 1) {
+                            start = start.lastChild;
+                        }
+                        if (!start || domUtils.isFillChar(start)){
+                            break;
+                        }
+                        offset = start.nodeValue.length;
+                    } else {
+                        start = range.startContainer;
+                        offset = range.startOffset;
+                    }
+                    range.setStart(start, offset - 1);
+                    charCode = range.toString().charCodeAt(0);
+                } while (charCode != 160 && charCode != 32);
+
+                if (range.toString().replace(new RegExp(domUtils.fillChar, 'g'), '').match(/(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i)) {
+                    while(range.toString().length){
+                        if(/^(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i.test(range.toString())){
+                            break;
+                        }
+                        try{
+                            range.setStart(range.startContainer,range.startOffset+1);
+                        }catch(e){
+                            //trace:2121
+                            var start = range.startContainer;
+                            while(!(next = start.nextSibling)){
+                                if(domUtils.isBody(start)){
+                                    return;
+                                }
+                                start = start.parentNode;
+
+                            }
+                            range.setStart(next,0);
+
+                        }
+
+                    }
+                    //range的开始边界已经在a标签里的不再处理
+                    if(domUtils.findParentByTagName(range.startContainer,'a',true)){
+                        return;
+                    }
+                    var a = me.document.createElement('a'),text = me.document.createTextNode(' '),href;
+
+                    me.undoManger && me.undoManger.save();
+                    a.appendChild(range.extractContents());
+                    a.href = a.innerHTML = a.innerHTML.replace(/<[^>]+>/g,'');
+                    href = a.getAttribute("href").replace(new RegExp(domUtils.fillChar,'g'),'');
+                    href = /^(?:https?:\/\/)/ig.test(href) ? href : "http://"+ href;
+                    a.setAttribute('data_ue_src',utils.html(href));
+                    a.href = utils.html(href);
+
+                    range.insertNode(a);
+                    a.parentNode.insertBefore(text, a.nextSibling);
+                    range.setStart(text, 0);
+                    range.collapse(true);
+                    sel.removeAllRanges();
+                    sel.addRange(range);
+                    me.undoManger && me.undoManger.save();
+                }
+            }
+        });
+    };

+ 24 - 0
web/js/ueditor2/_src/plugins/autosubmit.js

@@ -0,0 +1,24 @@
+///import core
+///commands 自动提交
+///commandsName  autosubmit
+///commandsTitle  自动提交
+UE.plugins['autosubmit'] = function(){
+    var me = this;
+    me.commands['autosubmit'] = {
+        execCommand:function () {
+            var me=this,
+                form = domUtils.findParentByTagName(me.iframe,"form", false);
+            if (form)    {
+                if(me.fireEvent("beforesubmit")===false){
+                    return;
+                }
+                me.sync();
+                form.submit();
+            }
+        }
+    };
+    //快捷键
+    me.addshortcutkey({
+        "autosubmit" : "ctrl+13" //手动提交
+    });
+};

+ 252 - 0
web/js/ueditor2/_src/plugins/autotypeset.js

@@ -0,0 +1,252 @@
+///import core
+///commands 自动排版
+///commandsName  autotypeset
+///commandsTitle  自动排版
+/**
+ * 自动排版
+ * @function
+ * @name baidu.editor.execCommands
+ */
+
+UE.plugins['autotypeset'] = function(){
+
+    this.setOpt({'autotypeset':{
+        mergeEmptyline : true,          //合并空行
+            removeClass : true,            //去掉冗余的class
+            removeEmptyline : false,        //去掉空行
+            textAlign : "left",             //段落的排版方式,可以是 left,right,center,justify 去掉这个属性表示不执行排版
+            imageBlockLine : 'center',      //图片的浮动方式,独占一行剧中,左右浮动,默认: center,left,right,none 去掉这个属性表示不执行排版
+            pasteFilter : false,             //根据规则过滤没事粘贴进来的内容
+            clearFontSize : false,           //去掉所有的内嵌字号,使用编辑器默认的字号
+            clearFontFamily : false,         //去掉所有的内嵌字体,使用编辑器默认的字体
+            removeEmptyNode : false,         // 去掉空节点
+            //可以去掉的标签
+            removeTagNames : utils.extend({div:1},dtd.$removeEmpty),
+            indent : false,                  // 行首缩进
+            indentValue : '2em'             //行首缩进的大小
+    }});
+    var me = this,
+        opt = me.options.autotypeset,
+        remainClass = {
+            'selectTdClass':1,
+            'pagebreak':1,
+            'anchorclass':1
+        },
+        remainTag = {
+            'li':1
+        },
+        tags = {
+            div:1,
+            p:1,
+            //trace:2183 这些也认为是行
+            blockquote:1,center:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,
+            span:1
+        },
+        highlightCont;
+    //升级了版本,但配置项目里没有autotypeset
+    if(!opt){
+        return;
+    }
+    function isLine(node,notEmpty){
+        if(!node || node.nodeType == 3)
+            return 0;
+        if(domUtils.isBr(node))
+            return 1;
+        if(node && node.parentNode && tags[node.tagName.toLowerCase()]){
+            if(highlightCont && highlightCont.contains(node)
+                ||
+                node.getAttribute('pagebreak')
+            ){
+                return 0;
+            }
+
+            return notEmpty ? !domUtils.isEmptyBlock(node) : domUtils.isEmptyBlock(node);
+        }
+    }
+
+    function removeNotAttributeSpan(node){
+        if(!node.style.cssText){
+            domUtils.removeAttributes(node,['style']);
+            if(node.tagName.toLowerCase() == 'span' && domUtils.hasNoAttributes(node)){
+                domUtils.remove(node,true);
+            }
+        }
+    }
+    function autotype(type,html){
+        var me = this,cont;
+        if(html){
+            if(!opt.pasteFilter){
+                return;
+            }
+            cont = me.document.createElement('div');
+            cont.innerHTML = html.html;
+        }else{
+            cont = me.document.body;
+        }
+        var nodes = domUtils.getElementsByTagName(cont,'*');
+
+          // 行首缩进,段落方向,段间距,段内间距
+        for(var i=0,ci;ci=nodes[i++];){
+
+            if(me.fireEvent('excludeNodeinautotype',ci) === true){
+                continue;
+            }
+             //font-size
+            if(opt.clearFontSize && ci.style.fontSize){
+                domUtils.removeStyle(ci,'font-size');
+
+                removeNotAttributeSpan(ci);
+
+            }
+            //font-family
+            if(opt.clearFontFamily && ci.style.fontFamily){
+                domUtils.removeStyle(ci,'font-family');
+                removeNotAttributeSpan(ci);
+            }
+
+            if(isLine(ci)){
+                //合并空行
+                if(opt.mergeEmptyline ){
+                    var next = ci.nextSibling,tmpNode,isBr = domUtils.isBr(ci);
+                    while(isLine(next)){
+                        tmpNode = next;
+                        next = tmpNode.nextSibling;
+                        if(isBr && (!next || next && !domUtils.isBr(next))){
+                            break;
+                        }
+                        domUtils.remove(tmpNode);
+                    }
+
+                }
+                 //去掉空行,保留占位的空行
+                if(opt.removeEmptyline && domUtils.inDoc(ci,cont) && !remainTag[ci.parentNode.tagName.toLowerCase()] ){
+                    if(domUtils.isBr(ci)){
+                        next = ci.nextSibling;
+                        if(next && !domUtils.isBr(next)){
+                            continue;
+                        }
+                    }
+                    domUtils.remove(ci);
+                    continue;
+
+                }
+
+            }
+            if(isLine(ci,true) && ci.tagName != 'SPAN'){
+                if(opt.indent){
+                    ci.style.textIndent = opt.indentValue;
+                }
+                if(opt.textAlign){
+                    ci.style.textAlign = opt.textAlign;
+                }
+//                if(opt.lineHeight)
+//                    ci.style.lineHeight = opt.lineHeight + 'cm';
+
+
+            }
+
+            //去掉class,保留的class不去掉
+            if(opt.removeClass && ci.className && !remainClass[ci.className.toLowerCase()]){
+
+                if(highlightCont && highlightCont.contains(ci)){
+                     continue;
+                }
+                domUtils.removeAttributes(ci,['class']);
+            }
+
+            //表情不处理
+            if(opt.imageBlockLine && ci.tagName.toLowerCase() == 'img' && !ci.getAttribute('emotion')){
+                if(html){
+                    var img = ci;
+                    switch (opt.imageBlockLine){
+                        case 'left':
+                        case 'right':
+                        case 'none':
+                            var pN = img.parentNode,tmpNode,pre,next;
+                            while(dtd.$inline[pN.tagName] || pN.tagName == 'A'){
+                                pN = pN.parentNode;
+                            }
+                            tmpNode = pN;
+                            if(tmpNode.tagName == 'P' && domUtils.getStyle(tmpNode,'text-align') == 'center'){
+                                if(!domUtils.isBody(tmpNode) && domUtils.getChildCount(tmpNode,function(node){return !domUtils.isBr(node) && !domUtils.isWhitespace(node)}) == 1){
+                                    pre = tmpNode.previousSibling;
+                                    next = tmpNode.nextSibling;
+                                    if(pre && next && pre.nodeType == 1 &&  next.nodeType == 1 && pre.tagName == next.tagName && domUtils.isBlockElm(pre)){
+                                        pre.appendChild(tmpNode.firstChild);
+                                        while(next.firstChild){
+                                            pre.appendChild(next.firstChild);
+                                        }
+                                        domUtils.remove(tmpNode);
+                                        domUtils.remove(next);
+                                    }else{
+                                        domUtils.setStyle(tmpNode,'text-align','');
+                                    }
+
+
+                                }
+
+
+                            }
+                            domUtils.setStyle(img,'float',opt.imageBlockLine);
+                            break;
+                        case 'center':
+                            if(me.queryCommandValue('imagefloat') != 'center'){
+                                pN = img.parentNode;
+                                domUtils.setStyle(img,'float','none');
+                                tmpNode = img;
+                                while(pN && domUtils.getChildCount(pN,function(node){return !domUtils.isBr(node) && !domUtils.isWhitespace(node)}) == 1
+                                    && (dtd.$inline[pN.tagName] || pN.tagName == 'A')){
+                                    tmpNode = pN;
+                                    pN = pN.parentNode;
+                                }
+                                var pNode = me.document.createElement('p');
+                                domUtils.setAttributes(pNode,{
+
+                                    style:'text-align:center'
+                                });
+                                tmpNode.parentNode.insertBefore(pNode,tmpNode);
+                                pNode.appendChild(tmpNode);
+                                domUtils.setStyle(tmpNode,'float','');
+
+                            }
+
+
+                    }
+                }else{
+                    var range = me.selection.getRange();
+                    range.selectNode(ci).select();
+                    me.execCommand('imagefloat',opt.imageBlockLine);
+                }
+
+
+
+            }
+
+            //去掉冗余的标签
+            if(opt.removeEmptyNode){
+                if(opt.removeTagNames[ci.tagName.toLowerCase()] && domUtils.hasNoAttributes(ci) && domUtils.isEmptyBlock(ci)){
+                    domUtils.remove(ci);
+                }
+            }
+        }
+        if(html){
+            html.html = cont.innerHTML;
+        }
+    }
+    if(opt.pasteFilter){
+        me.addListener('beforepaste',autotype);
+    }
+
+    me.commands['autotypeset'] = {
+        execCommand:function () {
+            me.removeListener('beforepaste',autotype);
+            if(opt.pasteFilter){
+                me.addListener('beforepaste',autotype);
+            }
+            autotype.call(me)
+        }
+
+    };
+
+};
+

+ 33 - 0
web/js/ueditor2/_src/plugins/background.js

@@ -0,0 +1,33 @@
+///import core
+///commands 插入背景
+///commandsName  background
+///commandsTitle  插入背景
+///commandsDialog  dialogs\background
+UE.plugins['background'] = function(){
+    var me = this;
+    me.addListener("getAllHtml",function(type,headHtml){
+        var body = this.body,
+            su = domUtils.getComputedStyle(body,"background-image"),
+            url="";
+        if(su.indexOf(me.options.imagePath)>0){
+            url =  su.substring(su.indexOf(me.options.imagePath),su.length-1).replace(/"|\(|\)/ig,"");
+        }else{
+            url =  su!="none" ? su.replace(/url\("?|"?\)/ig,""):"";
+        }
+        var html = '<style type="text/css">body{';
+        var bgObj = {
+            "background-color" : domUtils.getComputedStyle(body,"background-color")||"#ffffff",
+            'background-image' : url ? 'url('+url+')' : '',
+            'background-repeat':domUtils.getComputedStyle(body,"background-repeat")||"",
+            'background-position': browser.ie?(domUtils.getComputedStyle(body,"background-position-x")+" "+domUtils.getComputedStyle(body,"background-position-y")):domUtils.getComputedStyle(body,"background-position"),
+            'height':domUtils.getComputedStyle(body,"height")
+        };
+        for ( var name in bgObj ) {
+            if ( bgObj.hasOwnProperty( name ) ) {
+                html += name+":"+bgObj[name]+";";
+            }
+        }
+        html += '}</style> ';
+        headHtml.push(html);
+    });
+}

+ 68 - 0
web/js/ueditor2/_src/plugins/basestyle.js

@@ -0,0 +1,68 @@
+///import core
+///commands 加粗,斜体,上标,下标
+///commandsName  Bold,Italic,Subscript,Superscript
+///commandsTitle  加粗,加斜,下标,上标
+/**
+ * b u i等基础功能实现
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName    bold加粗。italic斜体。subscript上标。superscript下标。
+*/
+UE.plugins['basestyle'] = function(){
+    var basestyles = {
+            'bold':['strong','b'],
+            'italic':['em','i'],
+            'subscript':['sub'],
+            'superscript':['sup']
+        },
+        getObj = function(editor,tagNames){
+            return domUtils.filterNodeList(editor.selection.getStartElementPath(),tagNames);
+        },
+        me = this;
+    //添加快捷键
+    me.addshortcutkey({
+        "Bold" : "ctrl+66",//^B
+        "Italic" : "ctrl+73", //^I
+        "Underline" : "ctrl+85"//^U
+    });
+    for ( var style in basestyles ) {
+        (function( cmd, tagNames ) {
+            me.commands[cmd] = {
+                execCommand : function( cmdName ) {
+                    var range = me.selection.getRange(),obj = getObj(this,tagNames);
+                    if ( range.collapsed ) {
+                        if ( obj ) {
+                            var tmpText =  me.document.createTextNode('');
+                            range.insertNode( tmpText ).removeInlineStyle( tagNames );
+                            range.setStartBefore(tmpText);
+                            domUtils.remove(tmpText);
+                        } else {
+                            var tmpNode = range.document.createElement( tagNames[0] );
+                            if(cmdName == 'superscript' || cmdName == 'subscript'){
+                                tmpText = me.document.createTextNode('');
+                                range.insertNode(tmpText)
+                                    .removeInlineStyle(['sub','sup'])
+                                    .setStartBefore(tmpText)
+                                    .collapse(true);
+                            }
+                            range.insertNode( tmpNode ).setStart( tmpNode, 0 );
+                        }
+                        range.collapse( true );
+                    } else {
+                        if(cmdName == 'superscript' || cmdName == 'subscript'){
+                            if(!obj || obj.tagName.toLowerCase() != cmdName){
+                                range.removeInlineStyle(['sub','sup']);
+                            }
+                        }
+                        obj ? range.removeInlineStyle( tagNames ) : range.applyInlineStyle( tagNames[0] );
+                    }
+                    range.select();
+                },
+                queryCommandState : function() {
+                   return getObj(this,tagNames) ? 1 : 0;
+                }
+            };
+        })( style, basestyles[style] );
+    }
+};
+

+ 154 - 0
web/js/ueditor2/_src/plugins/blockquote.js

@@ -0,0 +1,154 @@
+///import core
+///commands 引用
+///commandsName  BlockQuote
+///commandsTitle  引用
+/**
+ * 
+ * 引用模块实现
+ * @function
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     blockquote引用
+ */
+
+
+UE.plugins['blockquote'] = function(){
+    var me = this;
+    function getObj(editor){
+        return domUtils.filterNodeList(editor.selection.getStartElementPath(),'blockquote');
+    };
+    me.commands['blockquote'] = {
+        execCommand : function( cmdName, attrs ) {
+            var range = this.selection.getRange(),
+                obj = getObj(this),
+                blockquote = dtd.blockquote,
+                bookmark = range.createBookmark();
+
+            if ( obj ) {
+
+
+                    var start = range.startContainer,
+                        startBlock = domUtils.isBlockElm(start) ? start : domUtils.findParent(start,function(node){return domUtils.isBlockElm(node)}),
+
+                        end = range.endContainer,
+                        endBlock = domUtils.isBlockElm(end) ? end :  domUtils.findParent(end,function(node){return domUtils.isBlockElm(node)});
+
+                    //处理一下li
+                    startBlock = domUtils.findParentByTagName(startBlock,'li',true) || startBlock;
+                    endBlock = domUtils.findParentByTagName(endBlock,'li',true) || endBlock;
+
+
+                    if(startBlock.tagName == 'LI' || startBlock.tagName == 'TD' || startBlock === obj){
+                        domUtils.remove(obj,true);
+                    }else{
+                        domUtils.breakParent(startBlock,obj);
+                    }
+
+                    if(startBlock !== endBlock){
+                        obj = domUtils.findParentByTagName(endBlock,'blockquote');
+                        if(obj){
+                            if(endBlock.tagName == 'LI' || endBlock.tagName == 'TD'){
+                                domUtils.remove(obj,true);
+                            }else{
+                                domUtils.breakParent(endBlock,obj);
+                            }
+
+                        }
+                    }
+
+                    var blockquotes = domUtils.getElementsByTagName(this.document,'blockquote');
+                    for(var i=0,bi;bi=blockquotes[i++];){
+                        if(!bi.childNodes.length){
+                            domUtils.remove(bi);
+                        }else if(domUtils.getPosition(bi,startBlock)&domUtils.POSITION_FOLLOWING && domUtils.getPosition(bi,endBlock)&domUtils.POSITION_PRECEDING){
+                            domUtils.remove(bi,true);
+                        }
+                    }
+
+
+
+
+            } else {
+
+                var tmpRange = range.cloneRange(),
+                    node = tmpRange.startContainer.nodeType == 1 ? tmpRange.startContainer : tmpRange.startContainer.parentNode,
+                    preNode = node,
+                    doEnd = 1;
+
+                //调整开始
+                while ( 1 ) {
+                    if ( domUtils.isBody(node) ) {
+                        if ( preNode !== node ) {
+                            if ( range.collapsed ) {
+                                tmpRange.selectNode( preNode );
+                                doEnd = 0;
+                            } else {
+                                tmpRange.setStartBefore( preNode );
+                            }
+                        }else{
+                            tmpRange.setStart(node,0);
+                        }
+
+                        break;
+                    }
+                    if ( !blockquote[node.tagName] ) {
+                        if ( range.collapsed ) {
+                            tmpRange.selectNode( preNode );
+                        } else{
+                            tmpRange.setStartBefore( preNode);
+                        }
+                        break;
+                    }
+
+                    preNode = node;
+                    node = node.parentNode;
+                }
+
+                //调整结束
+                if ( doEnd ) {
+                    preNode = node =  node = tmpRange.endContainer.nodeType == 1 ? tmpRange.endContainer : tmpRange.endContainer.parentNode;
+                    while ( 1 ) {
+
+                        if ( domUtils.isBody( node ) ) {
+                            if ( preNode !== node ) {
+
+                                tmpRange.setEndAfter( preNode );
+
+                            } else {
+                                tmpRange.setEnd( node, node.childNodes.length );
+                            }
+
+                            break;
+                        }
+                        if ( !blockquote[node.tagName] ) {
+                            tmpRange.setEndAfter( preNode );
+                            break;
+                        }
+
+                        preNode = node;
+                        node = node.parentNode;
+                    }
+
+                }
+
+
+                node = range.document.createElement( 'blockquote' );
+                domUtils.setAttributes( node, attrs );
+                node.appendChild( tmpRange.extractContents() );
+                tmpRange.insertNode( node );
+                //去除重复的
+                var childs = domUtils.getElementsByTagName(node,'blockquote');
+                for(var i=0,ci;ci=childs[i++];){
+                    if(ci.parentNode){
+                        domUtils.remove(ci,true);
+                    }
+                }
+
+            }
+            range.moveToBookmark( bookmark ).select();
+        },
+        queryCommandState : function() {
+            return getObj(this) ? 1 : 0;
+        }
+    };
+};
+

+ 95 - 0
web/js/ueditor2/_src/plugins/catchremoteimage.js

@@ -0,0 +1,95 @@
+///import core
+///commands 远程图片抓取
+///commandsName  catchRemoteImage,catchremoteimageenable
+///commandsTitle  远程图片抓取
+/**
+ * 远程图片抓取,当开启本插件时所有不符合本地域名的图片都将被抓取成为本地服务器上的图片
+ *
+ */
+UE.plugins['catchremoteimage'] = function () {
+    if (this.options.catchRemoteImageEnable===false){
+        return;
+    }
+    var me = this;
+    this.setOpt({
+        localDomain:["127.0.0.1","localhost","img.baidu.com"],
+        separater:'ue_separate_ue',
+        catchFieldName:"upfile",
+        catchRemoteImageEnable:true
+    });
+    var ajax = UE.ajax,
+        localDomain = me.options.localDomain ,
+        catcherUrl = me.options.catcherUrl,
+        separater = me.options.separater;
+    function catchremoteimage(imgs, callbacks) {
+        var submitStr = imgs.join(separater);
+        var tmpOption = {
+            timeout:60000, //单位:毫秒,回调请求超时设置。目标用户如果网速不是很快的话此处建议设置一个较大的数值
+            onsuccess:callbacks["success"],
+            onerror:callbacks["error"]
+        };
+        tmpOption[me.options.catchFieldName] = submitStr;
+        ajax.request(catcherUrl, tmpOption);
+    }
+
+    me.addListener("afterpaste", function () {
+        me.fireEvent("catchRemoteImage");
+    });
+
+    me.addListener("catchRemoteImage", function () {
+        var remoteImages = [];
+        var imgs = domUtils.getElementsByTagName(me.document, "img");
+        var test = function (src,urls) {
+            for (var j = 0, url; url = urls[j++];) {
+                if (src.indexOf(url) !== -1) {
+                    return true;
+                }
+            }
+            return false;
+        };
+        for (var i = 0, ci; ci = imgs[i++];) {
+            if (ci.getAttribute("word_img")){
+                continue;
+            }
+            var src = ci.getAttribute("data_ue_src") || ci.src || "";
+            if (/^(https?|ftp):/i.test(src) && !test(src,localDomain)) {
+                remoteImages.push(src);
+            }
+        }
+        if (remoteImages.length) {
+            catchremoteimage(remoteImages, {
+                //成功抓取
+                success:function (xhr) {
+                    try {
+                        var info = eval("(" + xhr.responseText + ")");
+                    } catch (e) {
+                        return;
+                    }
+                    var srcUrls = info.srcUrl.split(separater),
+                        urls = info.url.split(separater);
+                    for (var i = 0, ci; ci = imgs[i++];) {
+                        var src = ci.getAttribute("data_ue_src") || ci.src || "";
+                        for (var j = 0, cj; cj = srcUrls[j++];) {
+                            var url = urls[j - 1];
+                            if (src == cj && url != "error") {  //抓取失败时不做替换处理
+                                //地址修正
+                                var newSrc = me.options.catcherPath + url;
+                                domUtils.setAttributes(ci, {
+                                    "src":newSrc,
+                                    "data_ue_src":newSrc
+                                });
+                                break;
+                            }
+                        }
+                    }
+                    me.fireEvent('catchremotesuccess')
+                },
+                //回调失败,本次请求超时
+                error:function () {
+                    me.fireEvent("catchremoteerror");
+                }
+            });
+        }
+
+    });
+};

+ 28 - 0
web/js/ueditor2/_src/plugins/cleardoc.js

@@ -0,0 +1,28 @@
+///import core
+///commands 清空文档
+///commandsName  ClearDoc
+///commandsTitle  清空文档
+/**
+ *
+ * 清空文档
+ * @function
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     cleardoc清空文档
+ */
+
+UE.commands['cleardoc'] = {
+    execCommand : function( cmdName) {
+        var me = this,
+            enterTag = me.options.enterTag,
+            range = me.selection.getRange();
+        if(enterTag == "br"){
+            me.body.innerHTML = "<br/>";
+            range.setStart(me.body,0).setCursor();
+        }else{
+            me.body.innerHTML = "<p>"+(ie ? "" : "<br/>")+"</p>";
+            range.setStart(me.body.firstChild,0).setCursor(false,true);
+        }
+        me.fireEvent("clearDoc");
+    }
+};
+

+ 367 - 0
web/js/ueditor2/_src/plugins/contextmenu.js

@@ -0,0 +1,367 @@
+///import core
+///commands 右键菜单
+///commandsName  ContextMenu
+///commandsTitle  右键菜单
+/**
+ * 右键菜单
+ * @function
+ * @name baidu.editor.plugins.contextmenu
+ * @author zhanyi
+ */
+
+UE.plugins['contextmenu'] = function () {
+    var me = this,
+            lang = me.getLang( "contextMenu" ),
+            menu,
+            items = me.options.contextMenu || [
+                {label:lang['selectall'], cmdName:'selectall'},
+                {
+                    label:lang.deletecode,
+                    cmdName:'highlightcode',
+                    icon:'deletehighlightcode'
+                },
+                {
+                    label:lang.cleardoc,
+                    cmdName:'cleardoc',
+                    exec:function () {
+                        if ( confirm( lang.confirmclear ) ) {
+                            this.execCommand( 'cleardoc' );
+                        }
+                    }
+                },
+                {
+                    label:lang.clearcell,
+                    cmdName:'clearcell',
+                    exec:function () {
+                    	this.execCommand( 'clearcell' );
+                    }
+                },
+                '-',
+                {
+                    label:lang.unlink,
+                    cmdName:'unlink'
+                },
+                '-',
+                {
+                    group:lang.paragraph,
+                    icon:'justifyjustify',
+                    subMenu:[
+                        {
+                            label:lang.justifyleft,
+                            cmdName:'justify',
+                            value:'left'
+                        },
+                        {
+                            label:lang.justifyright,
+                            cmdName:'justify',
+                            value:'right'
+                        },
+                        {
+                            label:lang.justifycenter,
+                            cmdName:'justify',
+                            value:'center'
+                        },
+                        {
+                            label:lang.justifyjustify,
+                            cmdName:'justify',
+                            value:'justify'
+                        }
+                    ]
+                },
+                '-',
+                {
+                    group:lang.table,
+                    icon:'table',
+                    subMenu:[
+                        {
+                            label:lang.inserttable,
+                            cmdName:'inserttable'
+                        },
+                        {
+                            label:lang.deletetable,
+                            cmdName:'deletetable'
+                        },
+                        '-',
+                        {
+                            label:lang.deleterow,
+                            cmdName:'deleterow'
+                        },
+                        {
+                            label:lang.deletecol,
+                            cmdName:'deletecol'
+                        },
+                        {
+                            label:lang.insertcol,
+                            cmdName:'insertcol'
+                        },
+                        {
+                            label:lang.insertcolnext,
+                            cmdName:'insertcolnext'
+                        },
+                        {
+                            label:lang.insertrow,
+                            cmdName:'insertrow'
+                        },
+                        {
+                            label:lang.insertrownext,
+                            cmdName:'insertrownext'
+                        },
+                        '-',
+                        {
+                            label:lang.insertcaption,
+                            cmdName:'insertcaption'
+                        },
+                        {
+                            label:lang.deletecaption,
+                            cmdName:'deletecaption'
+                        },
+                        {
+                            label:lang.inserttitle,
+                            cmdName:'inserttitle'
+                        },
+                        {
+                            label:lang.deletetitle,
+                            cmdName:'deletetitle'
+                        },
+                        '-',
+                        {
+                            label:lang.mergecells,
+                            cmdName:'mergecells'
+                        },
+                        {
+                            label:lang.mergeright,
+                            cmdName:'mergeright'
+                        },
+                        {
+                            label:lang.mergedown,
+                            cmdName:'mergedown'
+                        },
+                        '-',
+                        {
+                            label:lang.splittorows,
+                            cmdName:'splittorows'
+                        },
+                        {
+                            label:lang.splittocols,
+                            cmdName:'splittocols'
+                        },
+                        {
+                            label:lang.splittocells,
+                            cmdName:'splittocells'
+                        },
+                        '-',
+                        {
+                            label:lang.averageDiseRow,
+                            cmdName:'averagedistributerow'
+                        },
+                        {
+                            label:lang.averageDisCol,
+                            cmdName:'averagedistributecol'
+                        },
+                        '-',
+                        {
+                            label:lang.edittd,
+                            cmdName:'edittd',
+                            exec:function () {
+                                if ( UE.ui['edittd'] ) {
+                                    new UE.ui['edittd']( this );
+                                }
+                                this.getDialog('edittd').open();
+                            }
+                        },
+                        {
+                            label:lang.edittable,
+                            cmdName:'edittable',
+                            exec:function () {
+                                if ( UE.ui['edittable'] ) {
+                                    new UE.ui['edittable']( this );
+                                }
+                                this.getDialog('edittable').open();
+                            }
+                        }
+                    ]
+                },                
+                {
+                    group:lang.aligntable,
+                    icon:'aligntable',
+                    subMenu:[
+                        {
+                            cmdName:'tablealignment',
+                            label:lang.tableleft,
+                            value:['float','left']
+                        },
+                        {
+                            cmdName:'tablealignment',
+                            label:lang.tablecenter,
+                            value:['margin','0 auto']
+                        },
+                        {
+                            cmdName:'tablealignment',
+                            label:lang.tableright,
+                            value:['float','right']
+                        }
+                    ]
+                },
+                '-',
+                {
+                    label:lang.insertparagraphbefore,
+                    cmdName:'insertparagraph',
+                    value:true
+                },
+                {
+                    label:lang.insertparagraphafter,
+                    cmdName:'insertparagraph'
+                },
+                {
+                    label:lang['copy'],
+                    cmdName:'copy',
+                    exec:function () {
+                        alert( lang.copymsg );
+                    },
+                    query:function () {
+                        return 0;
+                    }
+                },
+                {
+                    label:lang['paste'],
+                    cmdName:'paste',
+                    exec:function () {
+                        alert( lang.pastemsg );
+                    },
+                    query:function () {
+                        return 0;
+                    }
+                },{
+                    label:lang['highlightcode'],
+                    cmdName:'highlightcode',
+                    exec:function () {
+                        if ( UE.ui['highlightcode'] ) {
+                            new UE.ui['highlightcode']( this );
+                        }
+                        this.ui._dialogs['highlightcodeDialog'].open();
+                    }
+                }
+            ];
+    if ( !items.length ) {
+        return;
+    }
+    var uiUtils = UE.ui.uiUtils;
+    me.addListener( 'contextmenu', function ( type, evt ) {
+        var offset = uiUtils.getViewportOffsetByEvent( evt );
+        me.fireEvent( 'beforeselectionchange' );
+        if ( menu ) {
+            menu.destroy();
+        }
+        for ( var i = 0, ti, contextItems = []; ti = items[i]; i++ ) {
+            var last;
+            (function ( item ) {
+                if ( item == '-' ) {
+                    if ( (last = contextItems[contextItems.length - 1 ] ) && last !== '-' ) {
+                        contextItems.push( '-' );
+                    }
+                } else if ( item.hasOwnProperty( "group" ) ) {
+                    for ( var j = 0, cj, subMenu = []; cj = item.subMenu[j]; j++ ) {
+                        (function ( subItem ) {
+                            if ( subItem == '-' ) {
+                                if ( (last = subMenu[subMenu.length - 1 ] ) && last !== '-' ) {
+                                    subMenu.push( '-' );
+                                }else{
+                                    subMenu.splice(subMenu.length-1);
+                                }
+                            } else {
+                                if ( (me.commands[subItem.cmdName] || UE.commands[subItem.cmdName] || subItem.query) &&
+                                        (subItem.query ? subItem.query() : me.queryCommandState( subItem.cmdName )) > -1 ) {
+                                    subMenu.push( {
+                                        'label':subItem.label || me.getLang( "contextMenu." + subItem.cmdName + (subItem.value || '') )||"",
+                                        'className':'edui-for-' +subItem.cmdName,
+                                        onclick:subItem.exec ? function () {
+                                                subItem.exec.call( me );
+                                        } : function () {
+                                            me.execCommand( subItem.cmdName, subItem.value );
+                                        }
+                                    } );
+                                }
+                            }
+                        })( cj );
+                    }
+                    if ( subMenu.length ) {
+                        function getLabel(){
+                            switch (item.icon){
+                                case "table":
+                                    return me.getLang( "contextMenu.table" );
+                                case "justifyjustify":
+                                    return me.getLang( "contextMenu.paragraph" );
+                                case "aligntd":
+                                    return me.getLang("contextMenu.aligntd");
+                                case "aligntable":
+                                    return me.getLang("contextMenu.aligntable");
+                                default :
+                                    return '';
+                            }
+                        }
+                        contextItems.push( {
+                            //todo 修正成自动获取方式
+                            'label':getLabel(),
+                            className:'edui-for-' + item.icon,
+                            'subMenu':{
+                                items:subMenu,
+                                editor:me
+                            }
+                        } );
+                    }
+
+                } else {
+                    //有可能commmand没有加载右键不能出来,或者没有command也想能展示出来添加query方法
+                    if ( (me.commands[item.cmdName] || UE.commands[item.cmdName] || item.query) &&
+                            (item.query ? item.query.call(me) : me.queryCommandState( item.cmdName )) > -1 ) {
+                        //highlight todo
+                        if ( item.cmdName == 'highlightcode' ) {
+                            if(me.queryCommandState( item.cmdName ) == 1 && item.icon != 'deletehighlightcode'){
+                                return;
+                            }
+                            if(me.queryCommandState( item.cmdName ) != 1 && item.icon == 'deletehighlightcode'){
+                                return;
+                            }
+                        }
+                        contextItems.push( {
+                            'label':item.label || me.getLang( "contextMenu." + item.cmdName ),
+                            className:'edui-for-' + (item.icon ? item.icon : item.cmdName + (item.value || '')),
+                            onclick:item.exec ? function () {
+                                item.exec.call( me );
+                            } : function () {
+                                me.execCommand( item.cmdName, item.value );
+                            }
+                        } );
+                    }
+
+                }
+
+            })( ti );
+        }
+        if ( contextItems[contextItems.length - 1] == '-' ) {
+            contextItems.pop();
+        }
+        menu = new UE.ui.Menu( {
+            items:contextItems,
+            editor:me
+        } );
+        menu.render();
+        menu.showAt( offset );
+        domUtils.preventDefault( evt );
+        if ( browser.ie ) {
+            var ieRange;
+            try {
+                ieRange = me.selection.getNative().createRange();
+            } catch ( e ) {
+                return;
+            }
+            if ( ieRange.item ) {
+                var range = new dom.Range( me.document );
+                range.selectNode( ieRange.item( 0 ) ).select( true, true );
+
+            }
+        }
+    } );
+};
+
+

+ 39 - 0
web/js/ueditor2/_src/plugins/convertcase.js

@@ -0,0 +1,39 @@
+///import core
+///commands 大小写转换
+///commandsName touppercase,tolowercase
+///commandsTitle  大写,小写
+/**
+ * 大小写转换
+ * @function
+ * @name baidu.editor.execCommands
+ * @param    {String}    cmdName     cmdName="convertcase"
+ */
+UE.commands['touppercase'] =
+UE.commands['tolowercase'] = {
+    execCommand:function (cmd) {
+        var me = this;
+        var rng = me.selection.getRange();
+        if(rng.collapsed){
+            return rng;
+        }
+        var bk = rng.createBookmark(),
+            bkEnd = bk.end,
+            filterFn = function( node ) {
+                return !domUtils.isBr(node) && !domUtils.isWhitespace( node );
+            },
+            curNode = domUtils.getNextDomNode( bk.start, false, filterFn );
+        while ( curNode && (domUtils.getPosition( curNode, bkEnd ) & domUtils.POSITION_PRECEDING) ) {
+
+            if ( curNode.nodeType == 3 ) {
+                curNode.nodeValue = curNode.nodeValue[cmd == 'touppercase' ? 'toUpperCase' : 'toLowerCase']();
+            }
+            curNode = domUtils.getNextDomNode( curNode, true, filterFn );
+            if(curNode === bkEnd){
+                break;
+            }
+
+        }
+        rng.moveToBookmark(bk).select();
+    }
+};
+

+ 134 - 0
web/js/ueditor2/_src/plugins/customstyle.js

@@ -0,0 +1,134 @@
+///import core
+///commands 自定义样式
+///commandsName  CustomStyle
+///commandsTitle  自定义样式
+UE.plugins['customstyle'] = function() {
+    var me = this;
+    me.setOpt({ 'customstyle':[
+        {tag:'h1',name:'tc', style:'font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:center;margin:0 0 20px 0;'},
+        {tag:'h1',name:'tl', style:'font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:left;margin:0 0 10px 0;'},
+        {tag:'span',name:'im', style:'font-size:16px;font-style:italic;font-weight:bold;line-height:18px;'},
+        {tag:'span',name:'hi', style:'font-size:16px;font-style:italic;font-weight:bold;color:rgb(51, 153, 204);line-height:18px;'}
+    ]});
+    me.commands['customstyle'] = {
+        execCommand : function(cmdName, obj) {
+            var me = this,
+                    tagName = obj.tag,
+                    node = domUtils.findParent(me.selection.getStart(), function(node) {
+                        return node.getAttribute('label');
+                    }, true),
+                    range,bk,tmpObj = {};
+            for (var p in obj) {
+               if(obj[p]!==undefined)
+                    tmpObj[p] = obj[p];
+            }
+            delete tmpObj.tag;
+            if (node && node.getAttribute('label') == obj.label) {
+                range = this.selection.getRange();
+                bk = range.createBookmark();
+                if (range.collapsed) {
+                    //trace:1732 删掉自定义标签,要有p来回填站位
+                    if(dtd.$block[node.tagName]){
+                        var fillNode = me.document.createElement('p');
+                        domUtils.moveChild(node, fillNode);
+                        node.parentNode.insertBefore(fillNode, node);
+                        domUtils.remove(node);
+                    }else{
+                        domUtils.remove(node,true);
+                    }
+
+                } else {
+
+                    var common = domUtils.getCommonAncestor(bk.start, bk.end),
+                            nodes = domUtils.getElementsByTagName(common, tagName);
+                    if(new RegExp(tagName,'i').test(common.tagName)){
+                        nodes.push(common);
+                    }
+                    for (var i = 0,ni; ni = nodes[i++];) {
+                        if (ni.getAttribute('label') == obj.label) {
+                            var ps = domUtils.getPosition(ni, bk.start),pe = domUtils.getPosition(ni, bk.end);
+                            if ((ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS)
+                                    &&
+                                    (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS)
+                                    )
+                                if (dtd.$block[tagName]) {
+                                    var fillNode = me.document.createElement('p');
+                                    domUtils.moveChild(ni, fillNode);
+                                    ni.parentNode.insertBefore(fillNode, ni);
+                                }
+                            domUtils.remove(ni, true);
+                        }
+                    }
+                    node = domUtils.findParent(common, function(node) {
+                        return node.getAttribute('label') == obj.label;
+                    }, true);
+                    if (node) {
+
+                        domUtils.remove(node, true);
+
+                    }
+
+                }
+                range.moveToBookmark(bk).select();
+            } else {
+                if (dtd.$block[tagName]) {
+                    this.execCommand('paragraph', tagName, tmpObj,'customstyle');
+                    range = me.selection.getRange();
+                    if (!range.collapsed) {
+                        range.collapse();
+                        node = domUtils.findParent(me.selection.getStart(), function(node) {
+                            return node.getAttribute('label') == obj.label;
+                        }, true);
+                        var pNode = me.document.createElement('p');
+                        domUtils.insertAfter(node, pNode);
+                        domUtils.fillNode(me.document, pNode);
+                        range.setStart(pNode, 0).setCursor();
+                    }
+                } else {
+
+                    range = me.selection.getRange();
+                    if (range.collapsed) {
+                        node = me.document.createElement(tagName);
+                        domUtils.setAttributes(node, tmpObj);
+                        range.insertNode(node).setStart(node, 0).setCursor();
+
+                        return;
+                    }
+
+                    bk = range.createBookmark();
+                    range.applyInlineStyle(tagName, tmpObj).moveToBookmark(bk).select();
+                }
+            }
+
+        },
+        queryCommandValue : function() {
+            var parent = domUtils.filterNodeList(
+                this.selection.getStartElementPath(),
+                function(node){return node.getAttribute('label')}
+            );
+            return  parent ? parent.getAttribute('label') : '';
+        }
+    };
+    //当去掉customstyle是,如果是块元素,用p代替
+    me.addListener('keyup', function(type, evt) {
+        var keyCode = evt.keyCode || evt.which;
+
+        if (keyCode == 32 || keyCode == 13) {
+            var range = me.selection.getRange();
+            if (range.collapsed) {
+                var node = domUtils.findParent(me.selection.getStart(), function(node) {
+                    return node.getAttribute('label');
+                }, true);
+                if (node && dtd.$block[node.tagName] && domUtils.isEmptyNode(node)) {
+                        var p = me.document.createElement('p');
+                        domUtils.insertAfter(node, p);
+                        domUtils.fillNode(me.document, p);
+                        domUtils.remove(node);
+                        range.setStart(p, 0).setCursor();
+
+
+                }
+            }
+        }
+    });
+};

+ 103 - 0
web/js/ueditor2/_src/plugins/directionality.js

@@ -0,0 +1,103 @@
+///import core
+///commands 输入的方向
+///commandsName  DirectionalityLtr,DirectionalityRtl
+///commandsTitle  从左向右输入,从右向左输入
+/**
+ * 输入的方向
+ * @function
+ * @name baidu.editor.execCommand
+ * @param {String}   cmdName    directionality执行函数的参数
+ * @param {String}    forward    ltr从左向右输入,rtl从右向左输入
+ */
+(function() {
+    var block = domUtils.isBlockElm ,
+        getObj = function(editor){
+//            var startNode = editor.selection.getStart(),
+//                parents;
+//            if ( startNode ) {
+//                //查找所有的是block的父亲节点
+//                parents = domUtils.findParents( startNode, true, block, true );
+//                for ( var i = 0,ci; ci = parents[i++]; ) {
+//                    if ( ci.getAttribute( 'dir' ) ) {
+//                        return ci;
+//                    }
+//                }
+//            }
+            return domUtils.filterNodeList(editor.selection.getStartElementPath(),function(n){return n.getAttribute('dir')});
+
+        },
+        doDirectionality = function(range,editor,forward){
+            
+            var bookmark,
+                filterFn = function( node ) {
+                    return   node.nodeType == 1 ? !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace(node);
+                },
+
+                obj = getObj( editor );
+
+            if ( obj && range.collapsed ) {
+                obj.setAttribute( 'dir', forward );
+                return range;
+            }
+            bookmark = range.createBookmark();
+            range.enlarge( true );
+            var bookmark2 = range.createBookmark(),
+                current = domUtils.getNextDomNode( bookmark2.start, false, filterFn ),
+                tmpRange = range.cloneRange(),
+                tmpNode;
+            while ( current &&  !(domUtils.getPosition( current, bookmark2.end ) & domUtils.POSITION_FOLLOWING) ) {
+                if ( current.nodeType == 3 || !block( current ) ) {
+                    tmpRange.setStartBefore( current );
+                    while ( current && current !== bookmark2.end && !block( current ) ) {
+                        tmpNode = current;
+                        current = domUtils.getNextDomNode( current, false, null, function( node ) {
+                            return !block( node );
+                        } );
+                    }
+                    tmpRange.setEndAfter( tmpNode );
+                    var common = tmpRange.getCommonAncestor();
+                    if ( !domUtils.isBody( common ) && block( common ) ) {
+                        //遍历到了block节点
+                        common.setAttribute( 'dir', forward );
+                        current = common;
+                    } else {
+                        //没有遍历到,添加一个block节点
+                        var p = range.document.createElement( 'p' );
+                        p.setAttribute( 'dir', forward );
+                        var frag = tmpRange.extractContents();
+                        p.appendChild( frag );
+                        tmpRange.insertNode( p );
+                        current = p;
+                    }
+
+                    current = domUtils.getNextDomNode( current, false, filterFn );
+                } else {
+                    current = domUtils.getNextDomNode( current, true, filterFn );
+                }
+            }
+            return range.moveToBookmark( bookmark2 ).moveToBookmark( bookmark );
+        };
+    UE.commands['directionality'] = {
+        execCommand : function( cmdName,forward ) {
+            var range = this.selection.getRange();
+            //闭合时单独处理
+            if(range.collapsed){
+                var txt = this.document.createTextNode('d');
+                range.insertNode(txt);
+            }
+            doDirectionality(range,this,forward);
+            if(txt){
+                range.setStartBefore(txt).collapse(true);
+                domUtils.remove(txt);
+            }
+
+            range.select();
+            return true;
+        },
+        queryCommandValue : function() {
+            var node = getObj(this);
+            return node ? node.getAttribute('dir') : 'ltr';
+        }
+    };
+})();
+

+ 49 - 0
web/js/ueditor2/_src/plugins/elementpath.js

@@ -0,0 +1,49 @@
+///import core
+///commands 选区路径
+///commandsName  ElementPath,elementPathEnabled
+///commandsTitle  选区路径
+/**
+ * 选区路径
+ * @function
+ * @name baidu.editor.execCommand
+ * @param {String}     cmdName     elementpath选区路径
+ */
+UE.plugins['elementpath'] = function(){
+    var currentLevel,
+        tagNames,
+        me = this;
+    me.setOpt('elementPathEnabled',true);
+    if(!me.options.elementPathEnabled){
+        return;
+    }
+    me.commands['elementpath'] = {
+        execCommand : function( cmdName, level ) {
+            var start = tagNames[level],
+                range = me.selection.getRange();
+            currentLevel = level*1;
+            range.selectNode(start).select();
+        },
+        queryCommandValue : function() {
+            //产生一个副本,不能修改原来的startElementPath;
+            var parents = [].concat(this.selection.getStartElementPath()).reverse(),
+                names = [];
+            tagNames = parents;
+            for(var i=0,ci;ci=parents[i];i++){
+                if(ci.nodeType == 3) {
+                    continue;
+                }
+                var name = ci.tagName.toLowerCase();
+                if(name == 'img' && ci.getAttribute('anchorname')){
+                    name = 'anchor';
+                }
+                names[i] = name;
+                if(currentLevel == i){
+                   currentLevel = -1;
+                    break;
+                }
+            }
+            return names;
+        }
+    };
+};
+

+ 192 - 0
web/js/ueditor2/_src/plugins/enterkey.js

@@ -0,0 +1,192 @@
+///import core
+///import plugins/undo.js
+///commands 设置回车标签p或br
+///commandsName  EnterKey
+///commandsTitle  设置回车标签p或br
+/**
+ * @description 处理回车
+ * @author zhanyi
+ */
+UE.plugins['enterkey'] = function() {
+    var hTag,
+        me = this,
+        tag = me.options.enterTag;
+    me.addListener('keyup', function(type, evt) {
+
+        var keyCode = evt.keyCode || evt.which;
+        if (keyCode == 13) {
+            var range = me.selection.getRange(),
+                start = range.startContainer,
+                doSave;
+
+            //修正在h1-h6里边回车后不能嵌套p的问题
+            if (!browser.ie) {
+
+                if (/h\d/i.test(hTag)) {
+                    if (browser.gecko) {
+                        var h = domUtils.findParentByTagName(start, [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6','blockquote','caption','table'], true);
+                        if (!h) {
+                            me.document.execCommand('formatBlock', false, '<p>');
+                            doSave = 1;
+                        }
+                    } else {
+                        //chrome remove div
+                        if (start.nodeType == 1) {
+                            var tmp = me.document.createTextNode(''),div;
+                            range.insertNode(tmp);
+                            div = domUtils.findParentByTagName(tmp, 'div', true);
+                            if (div) {
+                                var p = me.document.createElement('p');
+                                while (div.firstChild) {
+                                    p.appendChild(div.firstChild);
+                                }
+                                div.parentNode.insertBefore(p, div);
+                                domUtils.remove(div);
+                                range.setStartBefore(tmp).setCursor();
+                                doSave = 1;
+                            }
+                            domUtils.remove(tmp);
+
+                        }
+                    }
+
+                    if (me.undoManger && doSave) {
+                        me.undoManger.save();
+                    }
+                }
+                //没有站位符,会出现多行的问题
+                browser.opera &&  range.select();
+            }
+//            if(browser.ie){
+//                range = me.selection.getRange();
+//                start = range.startContainer;
+//                while(start){
+//                    if(start.nodeType == 1 && start.tagName == 'P'){
+//                        break;
+//                    }
+//                    start = start.parentNode;
+//                }
+//                if(start && domUtils.isEmptyBlock(start)){
+//                    start.innerHTML = '&nbsp;';
+//                    var rng = me.selection.getRange();
+//                    rng.setStart(start,0).setCursor(false,true);
+//                }
+//            }
+
+
+            setTimeout(function() {
+                me.selection.getRange().scrollToView(me.autoHeightEnabled, me.autoHeightEnabled ? domUtils.getXY(me.iframe).y : 0);
+            }, 50);
+
+        }
+    });
+
+    me.addListener('keydown', function(type, evt) {
+        var keyCode = evt.keyCode || evt.which;
+        if (keyCode == 13) {//回车
+            if (me.undoManger) {
+                me.undoManger.save();
+            }
+            hTag = '';
+
+
+            var range = me.selection.getRange();
+
+            if (!range.collapsed) {
+                //跨td不能删
+                var start = range.startContainer,
+                    end = range.endContainer,
+                    startTd = domUtils.findParentByTagName(start, 'td', true),
+                    endTd = domUtils.findParentByTagName(end, 'td', true);
+                if (startTd && endTd && startTd !== endTd || !startTd && endTd || startTd && !endTd) {
+                    evt.preventDefault ? evt.preventDefault() : ( evt.returnValue = false);
+                    return;
+                }
+            }
+            if (tag == 'p') {
+
+
+                if (!browser.ie) {
+
+                    start = domUtils.findParentByTagName(range.startContainer, ['ol','ul','p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6','blockquote','caption'], true);
+
+                    //opera下执行formatblock会在table的场景下有问题,回车在opera原生支持很好,所以暂时在opera去掉调用这个原生的command
+                    //trace:2431
+                    if (!start && !browser.opera) {
+
+                        me.document.execCommand('formatBlock', false, '<p>');
+
+                        if (browser.gecko) {
+                            range = me.selection.getRange();
+                            start = domUtils.findParentByTagName(range.startContainer, 'p', true);
+                            start && domUtils.removeDirtyAttr(start);
+                        }
+
+
+                    } else {
+                        hTag = start.tagName;
+                        start.tagName.toLowerCase() == 'p' && browser.gecko && domUtils.removeDirtyAttr(start);
+                    }
+
+                }
+
+            } else {
+                evt.preventDefault ? evt.preventDefault() : ( evt.returnValue = false);
+
+                if (!range.collapsed) {
+                    range.deleteContents();
+                    start = range.startContainer;
+                    if (start.nodeType == 1 && (start = start.childNodes[range.startOffset])) {
+                        while (start.nodeType == 1) {
+                            if (dtd.$empty[start.tagName]) {
+                                range.setStartBefore(start).setCursor();
+                                if (me.undoManger) {
+                                    me.undoManger.save();
+                                }
+                                return false;
+                            }
+                            if (!start.firstChild) {
+                                var br = range.document.createElement('br');
+                                start.appendChild(br);
+                                range.setStart(start, 0).setCursor();
+                                if (me.undoManger) {
+                                    me.undoManger.save();
+                                }
+                                return false;
+                            }
+                            start = start.firstChild;
+                        }
+                        if (start === range.startContainer.childNodes[range.startOffset]) {
+                            br = range.document.createElement('br');
+                            range.insertNode(br).setCursor();
+
+                        } else {
+                            range.setStart(start, 0).setCursor();
+                        }
+
+
+                    } else {
+                        br = range.document.createElement('br');
+                        range.insertNode(br).setStartAfter(br).setCursor();
+                    }
+
+
+                } else {
+                    br = range.document.createElement('br');
+                    range.insertNode(br);
+                    var parent = br.parentNode;
+                    if (parent.lastChild === br) {
+                        br.parentNode.insertBefore(br.cloneNode(true), br);
+                        range.setStartBefore(br);
+                    } else {
+                        range.setStartAfter(br);
+                    }
+                    range.setCursor();
+
+                }
+
+            }
+
+        }
+    });
+};

+ 18 - 0
web/js/ueditor2/_src/plugins/fiximgclick.js

@@ -0,0 +1,18 @@
+///import core
+///commands 修复chrome下图片不能点击的问题
+///commandsName  FixImgClick
+///commandsTitle  修复chrome下图片不能点击的问题
+//修复chrome下图片不能点击的问题
+//todo 可以改大小
+UE.plugins['fiximgclick'] = function() {
+    var me = this;
+    if ( browser.webkit ) {
+        me.addListener( 'click', function( type, e ) {
+            if ( e.target.tagName == 'IMG' ) {
+                var range = new dom.Range( me.document );
+                range.selectNode( e.target ).select();
+
+            }
+        } );
+    }
+};

+ 174 - 0
web/js/ueditor2/_src/plugins/font.js

@@ -0,0 +1,174 @@
+///import core
+///import plugins\removeformat.js
+///commands 字体颜色,背景色,字号,字体,下划线,删除线
+///commandsName  ForeColor,BackColor,FontSize,FontFamily,Underline,StrikeThrough
+///commandsTitle  字体颜色,背景色,字号,字体,下划线,删除线
+/**
+ * @description 字体
+ * @name baidu.editor.execCommand
+ * @param {String}     cmdName    执行的功能名称
+ * @param {String}    value             传入的值
+ */
+UE.plugins['font'] = function() {
+    var me = this,
+        fonts = {
+            'forecolor':'color',
+            'backcolor':'background-color',
+            'fontsize':'font-size',
+            'fontfamily':'font-family',
+            'underline':'text-decoration',
+            'strikethrough':'text-decoration'
+        };
+    me.setOpt({
+        'fontfamily':[
+            { name:'songti',val:'宋体,SimSun'},
+            { name:'yahei',val:'微软雅黑,Microsoft YaHei'},
+            { name:'kaiti',val:'楷体,楷体_GB2312, SimKai'},
+            { name:'heiti',val:'黑体, SimHei'},
+            { name:'lishu',val:'隶书, SimLi'},
+            { name:'andaleMono',val:'andale mono'},
+            { name:'arial',val:'arial, helvetica,sans-serif'},
+            { name:'arialBlack',val:'arial black,avant garde'},
+            { name:'comicSansMs',val:'comic sans ms'},
+            { name:'impact',val:'impact,chicago'},
+            { name:'timesNewRoman',val:'times new roman'}
+          ],
+        'fontsize':[10, 11, 12, 14, 16, 18, 20, 24, 36]
+    });
+
+    for ( var p in fonts ) {
+        (function( cmd, style ) {
+            UE.commands[cmd] = {
+                execCommand : function( cmdName, value ) {
+                    value = value || (this.queryCommandState(cmdName) ? 'none' : cmdName == 'underline' ? 'underline' : 'line-through');
+                    var me = this,
+                        range = this.selection.getRange(),
+                        text;
+
+                    if ( value == 'default' ) {
+
+                        if(range.collapsed){
+                            text = me.document.createTextNode('font');
+                            range.insertNode(text).select();
+
+                        }
+                        me.execCommand( 'removeFormat', 'span,a', style);
+                        if(text){
+                            range.setStartBefore(text).setCursor();
+                            domUtils.remove(text);
+                        }
+
+
+                    } else {
+
+                            if ( !range.collapsed ) {
+                                if((cmd == 'underline'||cmd=='strikethrough') && me.queryCommandValue(cmd)){
+                                     me.execCommand( 'removeFormat', 'span,a', style );
+                                }
+                                range = me.selection.getRange();
+
+                                range.applyInlineStyle( 'span', {'style':style + ':' + value} ).select();
+                            } else {
+
+                                var span = domUtils.findParentByTagName(range.startContainer,'span',true);
+                                text = me.document.createTextNode('font');
+                                if(span && !span.children.length && !span[browser.ie ? 'innerText':'textContent'].replace(fillCharReg,'').length){
+                                    //for ie hack when enter
+                                    range.insertNode(text);
+                                     if(cmd == 'underline'||cmd=='strikethrough'){
+                                         range.selectNode(text).select();
+                                         me.execCommand( 'removeFormat','span,a', style, null );
+
+                                         span = domUtils.findParentByTagName(text,'span',true);
+                                         range.setStartBefore(text);
+
+                                    }
+                                    span.style.cssText += ';' + style + ':' + value;
+                                    range.collapse(true).select();
+
+
+                                }else{
+                                    range.insertNode(text);
+                                    range.selectNode(text).select();
+                                    span = range.document.createElement( 'span' );
+
+                                    if(cmd == 'underline'||cmd=='strikethrough'){
+                                        //a标签内的不处理跳过
+                                        if(domUtils.findParentByTagName(text,'a',true)){
+                                            range.setStartBefore(text).setCursor();
+                                             domUtils.remove(text);
+                                             return;
+                                         }
+                                         me.execCommand( 'removeFormat','span,a', style );
+                                    }
+
+                                    span.style.cssText = style + ':' + value;
+
+
+                                    text.parentNode.insertBefore(span,text);
+                                    //修复,span套span 但样式不继承的问题
+                                    if(!browser.ie || browser.ie && browser.version == 9){
+                                        var spanParent = span.parentNode;
+                                        while(!domUtils.isBlockElm(spanParent)){
+                                            if(spanParent.tagName == 'SPAN'){
+                                                //opera合并style不会加入";"
+                                                span.style.cssText = spanParent.style.cssText + ";" + span.style.cssText;
+                                            }
+                                            spanParent = spanParent.parentNode;
+                                        }
+                                    }
+
+
+                                    if(opera){
+                                        setTimeout(function(){
+                                            range.setStart(span,0).setCursor();
+                                        });
+                                    }else{
+                                        range.setStart(span,0).setCursor();
+                                    }
+
+                                    //trace:981
+                                    //domUtils.mergeToParent(span)
+
+
+                                }
+                                domUtils.remove(text);
+                            }
+
+
+                    }
+                    return true;
+                },
+                queryCommandValue : function (cmdName) {
+                    var startNode = this.selection.getStart();
+
+                    //trace:946
+                    if(cmdName == 'underline'||cmdName=='strikethrough' ){
+                        var tmpNode = startNode,value;
+                        while(tmpNode && !domUtils.isBlockElm(tmpNode) && !domUtils.isBody(tmpNode)){
+                            if(tmpNode.nodeType == 1){
+                                value = domUtils.getComputedStyle( tmpNode, style );
+
+                                if(value != 'none'){
+                                    return value;
+                                }
+                            }
+
+                            tmpNode = tmpNode.parentNode;
+                        }
+                        return 'none';
+                    }
+                    return  domUtils.getComputedStyle( startNode, style );
+                },
+                queryCommandState : function(cmdName){
+                    if(!(cmdName == 'underline'||cmdName=='strikethrough')){
+                        return 0;
+                    }
+                    return this.queryCommandValue(cmdName) == (cmdName == 'underline' ? 'underline' : 'line-through');
+                }
+            };
+        })( p, fonts[p] );
+    }
+
+
+};

+ 129 - 0
web/js/ueditor2/_src/plugins/formatmatch.js

@@ -0,0 +1,129 @@
+///import core
+///import plugins\removeformat.js
+///commands 格式刷
+///commandsName  FormatMatch
+///commandsTitle  格式刷
+/**
+ * 格式刷,只格式inline的
+ * @function
+ * @name baidu.editor.execCommand
+ * @param {String}     cmdName    formatmatch执行格式刷
+ */
+UE.plugins['formatmatch'] = function(){
+
+    var me = this,
+        list = [],img,
+        flag = 0;
+
+     me.addListener('reset',function(){
+         list = [];
+         flag = 0;
+     });
+
+    function addList(type,evt){
+        
+        if(browser.webkit){
+            var target = evt.target.tagName == 'IMG' ? evt.target : null;
+        }
+
+        function addFormat(range){
+
+            if(text){
+                range.selectNode(text);
+            }
+            return range.applyInlineStyle(list[list.length-1].tagName,null,list);
+
+        }
+
+        me.undoManger && me.undoManger.save();
+
+        var range = me.selection.getRange(),
+            imgT = target || range.getClosedNode();
+        if(img && imgT && imgT.tagName == 'IMG'){
+            //trace:964
+
+            imgT.style.cssText += ';float:' + (img.style.cssFloat || img.style.styleFloat ||'none') + ';display:' + (img.style.display||'inline');
+
+            img = null;
+        }else{
+            if(!img){
+                var collapsed = range.collapsed;
+                if(collapsed){
+                    var text = me.document.createTextNode('match');
+                    range.insertNode(text).select();
+
+
+                }
+                me.__hasEnterExecCommand = true;
+                //不能把block上的属性干掉
+                //trace:1553
+                var removeFormatAttributes = me.options.removeFormatAttributes;
+                me.options.removeFormatAttributes = '';
+                me.execCommand('removeformat');
+                me.options.removeFormatAttributes = removeFormatAttributes;
+                me.__hasEnterExecCommand = false;
+                //trace:969
+                range = me.selection.getRange();
+                if(list.length){
+                    addFormat(range);
+                }
+                if(text){
+                    range.setStartBefore(text).collapse(true);
+
+                }
+                range.select();
+                text && domUtils.remove(text);
+            }
+
+        }
+
+
+
+
+        me.undoManger && me.undoManger.save();
+        me.removeListener('mouseup',addList);
+        flag = 0;
+    }
+
+    me.commands['formatmatch'] = {
+        execCommand : function( cmdName ) {
+          
+            if(flag){
+                flag = 0;
+                list = [];
+                 me.removeListener('mouseup',addList);
+                return;
+            }
+
+
+              
+            var range = me.selection.getRange();
+            img = range.getClosedNode();
+            if(!img || img.tagName != 'IMG'){
+               range.collapse(true).shrinkBoundary();
+               var start = range.startContainer;
+               list = domUtils.findParents(start,true,function(node){
+                   return !domUtils.isBlockElm(node) && node.nodeType == 1;
+               });
+               //a不能加入格式刷, 并且克隆节点
+               for(var i=0,ci;ci=list[i];i++){
+                   if(ci.tagName == 'A'){
+                       list.splice(i,1);
+                       break;
+                   }
+               }
+
+            }
+
+            me.addListener('mouseup',addList);
+            flag = 1;
+
+
+        },
+        queryCommandState : function() {
+            return flag;
+        },
+        notNeedUndo : 1
+    };
+};
+

+ 193 - 0
web/js/ueditor2/_src/plugins/highlightcode.js

@@ -0,0 +1,193 @@
+///import core
+///import plugins/inserthtml.js
+///commands 插入代码
+///commandsName  HighlightCode
+///commandsTitle  插入代码
+///commandsDialog  dialogs\highlightcode
+UE.plugins['highlightcode'] = function() {
+    var me = this;
+    if(!/highlightcode/i.test(me.options.toolbars.join(''))){
+        return;
+    }
+
+    me.commands['highlightcode'] = {
+        execCommand: function (cmdName, code, syntax) {
+            var range = this.selection.getRange(),
+                start = domUtils.findParentByTagName(range.startContainer, 'table', true),
+                end = domUtils.findParentByTagName(range.endContainer, 'table', true);
+            if(start && end && start === end && domUtils.hasClass(start,'syntaxhighlighter')){
+                if(start.nextSibling){
+                    range.setStart(start.nextSibling,0)
+                }else{
+                    if(start.previousSibling){
+                        range.setStartAtLast(start.previousSibling)
+                    }else{
+                        var p = me.document.createElement('p');
+                        domUtils.fillNode(me.document,p);
+                        start.parentNode.insertBefore(p,start);
+                        range.setStart(p,0)
+                    }
+                }
+                range.setCursor(false,true);
+                domUtils.remove(start);
+            }
+            if(code && syntax){
+                me.execCommand('inserthtml','<pre id="highlightcode_id" class="brush: '+syntax+';toolbar:false;">'+utils.unhtml(code)+'</pre>',true);
+                var pre = me.document.getElementById('highlightcode_id');
+                if(pre){
+                    domUtils.removeAttributes(pre,'id');
+                    me.window.SyntaxHighlighter.highlight(pre);
+                }
+            }
+
+        },
+        queryCommandState: function(){
+            return queryHighlight.call(this);
+        }
+    };
+
+    function queryHighlight(){
+        try{
+            var range = this.selection.getRange(),start,end;
+            range.adjustmentBoundary();
+            start = domUtils.findParent(range.startContainer,function(node){
+                return node.nodeType == 1 && node.tagName == 'TABLE' && domUtils.hasClass(node,'syntaxhighlighter');
+            },true);
+            end = domUtils.findParent(range.endContainer,function(node){
+                return node.nodeType == 1 && node.tagName == 'TABLE' && domUtils.hasClass(node,'syntaxhighlighter');
+            },true);
+            return start && end && start == end  ? 1 : 0;
+        }catch(e){
+            return 0;
+        }
+    }
+
+    //不需要判断highlight的command列表
+    me.notNeedHighlightQuery ={
+        help:1,
+        undo:1,
+        redo:1,
+        source:1,
+        print:1,
+        searchreplace:1,
+        fullscreen:1,
+        preview:1,
+        insertparagraph:1,
+        elementpath:1,
+        highlightcode:1
+    };
+    //将queyCommamndState重置
+    var orgQuery = me.queryCommandState;
+    me.queryCommandState = function(cmd){
+        if(!me.notNeedHighlightQuery[cmd.toLowerCase()] && queryHighlight.call(this) == 1){
+            return -1;
+        }
+        return orgQuery.apply(this,arguments)
+    };
+
+    me.addListener('beforeselectionchange afterselectionchange',function(type){
+        me.highlight = /^b/.test(type) ? me.queryCommandState('highlightcode') : 0;
+    });
+
+
+    me.addListener("ready",function(){
+        //避免重复加载高亮文件
+        if(typeof me.XRegExp == "undefined"){
+            utils.loadFile(me.document,{
+                id : "syntaxhighlighter_js",
+                src : me.options.highlightJsUrl || me.options.UEDITOR_HOME_URL + "third-party/SyntaxHighlighter/shCore.js",
+                tag : "script",
+                type : "text/javascript",
+                defer : "defer"
+            },function(){
+                changePre.call(me);
+            });
+        }
+        if(!me.document.getElementById("syntaxhighlighter_css")){
+            utils.loadFile(me.document,{
+                id : "syntaxhighlighter_css",
+                tag : "link",
+                rel : "stylesheet",
+                type : "text/css",
+                href : me.options.highlightCssUrl ||me.options.UEDITOR_HOME_URL + "third-party/SyntaxHighlighter/shCoreDefault.css"
+            });
+        }
+
+    });
+    me.addListener("beforegetcontent beforegetscene",function(){
+        utils.each(domUtils.getElementsByTagName(me.body,'table','syntaxhighlighter'),function(di){
+            var str = [],parentCode = '';
+            utils.each(di.getElementsByTagName('code'),function(ci){
+                if(parentCode !== ci.parentNode){
+                    parentCode = ci.parentNode;
+                    //去掉左右空格,针对ie的不能回退的问题
+                    str.push(utils.trim(parentCode[browser.ie?'innerText':'textContent']))
+                }
+
+            });
+            var pre = domUtils.createElement(me.document,'pre',{
+                'class' : 'brush: '+di.className.replace(/\s+/g,' ').split(' ')[1]+';toolbar:false;'
+            });
+            pre.appendChild(me.document.createTextNode(str.join('\n')));
+            di.parentNode.replaceChild(pre,di);
+        });
+    });
+    me.addListener("aftergetcontent aftersetcontent aftergetscene",changePre);
+
+
+    //避免table插件对于代码高亮的影响
+    me.addListener('excludetable excludeNodeinautotype',function (cmd,target){
+        if(target && domUtils.findParent(target,function(node){
+            return domUtils.hasClass(node,'syntaxhighlighter');
+        },true)){
+            return true;
+        }
+    });
+
+    function changePre(){
+        var me = this;
+        if(!me.window||!me.window.SyntaxHighlighter)return;
+        utils.each(domUtils.getElementsByTagName(me.document,"pre"),function(pi){
+            if(domUtils.hasClass(pi,'brush')){
+                me.window.SyntaxHighlighter.highlight(pi);
+            }
+        });
+    }
+
+    me.addListener('getAllHtml',function(type,headHtml){
+        var coreHtml = '';
+        for(var i= 0,ci,divs=domUtils.getElementsByTagName(me.document,'table');ci=divs[i++];){
+            if(domUtils.hasClass(ci,'syntaxhighlighter')){
+                coreHtml = '<script type="text/javascript">window.onload = function(){SyntaxHighlighter.highlight();' +
+                    'setTimeout(function(){ '+
+                     "   var tables = document.getElementsByTagName('table');"+
+                     "   for(var t= 0,ti;ti=tables[t++];){"+
+                     "       if(/SyntaxHighlighter/i.test(ti.className)){"+
+                     "           var tds = ti.getElementsByTagName('td');"+
+                     "           for(var i=0,li,ri;li=tds[0].childNodes[i];i++){"+
+                     "               ri = tds[1].firstChild.childNodes[i];"+
+                     "               if(ri){"+
+                     "                  ri.style.height = li.style.height = ri.offsetHeight + 'px';"+
+                     "               }"+
+                     "           }"+
+                     "       }"+
+                     "   }"+
+                    '},100)' +
+                    '}</script>'
+                break;
+            }
+        }
+        if(!coreHtml){
+            var tmpNode;
+            if(tmpNode = me.document.getElementById('syntaxhighlighter_css')){
+                domUtils.remove(tmpNode)
+            }
+            if(tmpNode = me.document.getElementById('syntaxhighlighter_js')){
+                domUtils.remove(tmpNode)
+
+            }
+        }
+        coreHtml && headHtml.push(coreHtml)
+    });
+
+};

+ 46 - 0
web/js/ueditor2/_src/plugins/horizontal.js

@@ -0,0 +1,46 @@
+///import core
+///import plugins\inserthtml.js
+///commands 分割线
+///commandsName  Horizontal
+///commandsTitle  分隔线
+/**
+ * 分割线
+ * @function
+ * @name baidu.editor.execCommand
+ * @param {String}     cmdName    horizontal插入分割线
+ */
+UE.commands['horizontal'] = {
+    execCommand : function( cmdName ) {
+        var me = this;
+        if(me.queryCommandState(cmdName)!==-1){
+            me.execCommand('insertHtml','<hr>');
+            var range = me.selection.getRange(),
+                start = range.startContainer;
+            if(start.nodeType == 1 && !start.childNodes[range.startOffset] ){
+
+                var tmp;
+                if(tmp = start.childNodes[range.startOffset - 1]){
+                    if(tmp.nodeType == 1 && tmp.tagName == 'HR'){
+                        if(me.options.enterTag == 'p'){
+                            tmp = me.document.createElement('p');
+                            range.insertNode(tmp);
+                            range.setStart(tmp,0).setCursor();
+
+                        }else{
+                            tmp = me.document.createElement('br');
+                            range.insertNode(tmp);
+                            range.setStartBefore(tmp).setCursor();
+                        }
+                    }
+                }
+
+            }
+            return true;
+        }
+
+    },
+    //边界在table里不能加分隔线
+    queryCommandState : function() {
+        return domUtils.filterNodeList(this.selection.getStartElementPath(),'table') ? -1 : 0;
+    }
+};

+ 19 - 0
web/js/ueditor2/_src/plugins/iframe.js

@@ -0,0 +1,19 @@
+///import core
+///import plugins\inserthtml.js
+///commands 插入框架
+///commandsName  InsertFrame
+///commandsTitle  插入Iframe
+///commandsDialog  dialogs\insertframe
+
+UE.plugins['insertframe'] = function() {
+   var me =this;
+    function deleteIframe(){
+        me._iframe && delete me._iframe;
+    }
+
+    me.addListener("selectionchange",function(){
+        deleteIframe();
+    });
+
+};
+

+ 188 - 0
web/js/ueditor2/_src/plugins/image.js

@@ -0,0 +1,188 @@
+///import core
+///import plugins\inserthtml.js
+///commands 插入图片,操作图片的对齐方式
+///commandsName  InsertImage,ImageNone,ImageLeft,ImageRight,ImageCenter
+///commandsTitle  图片,默认,居左,居右,居中
+///commandsDialog  dialogs\image
+/**
+ * Created by .
+ * User: zhanyi
+ * for image
+ */
+
+UE.commands['imagefloat'] = {
+    execCommand:function (cmd, align) {
+        var me = this,
+            range = me.selection.getRange();
+        if (!range.collapsed) {
+            var img = range.getClosedNode();
+            if (img && img.tagName == 'IMG') {
+                switch (align) {
+                    case 'left':
+                    case 'right':
+                    case 'none':
+                        var pN = img.parentNode, tmpNode, pre, next;
+                        while (dtd.$inline[pN.tagName] || pN.tagName == 'A') {
+                            pN = pN.parentNode;
+                        }
+                        tmpNode = pN;
+                        if (tmpNode.tagName == 'P' && domUtils.getStyle(tmpNode, 'text-align') == 'center') {
+                            if (!domUtils.isBody(tmpNode) && domUtils.getChildCount(tmpNode, function (node) {
+                                return !domUtils.isBr(node) && !domUtils.isWhitespace(node);
+                            }) == 1) {
+                                pre = tmpNode.previousSibling;
+                                next = tmpNode.nextSibling;
+                                if (pre && next && pre.nodeType == 1 && next.nodeType == 1 && pre.tagName == next.tagName && domUtils.isBlockElm(pre)) {
+                                    pre.appendChild(tmpNode.firstChild);
+                                    while (next.firstChild) {
+                                        pre.appendChild(next.firstChild);
+                                    }
+                                    domUtils.remove(tmpNode);
+                                    domUtils.remove(next);
+                                } else {
+                                    domUtils.setStyle(tmpNode, 'text-align', '');
+                                }
+
+
+                            }
+
+                            range.selectNode(img).select();
+                        }
+                        domUtils.setStyle(img, 'float', align == 'none' ? '' : align);
+                        if(align == 'none'){
+                            domUtils.removeAttributes(img,'align');
+                        }
+
+                        break;
+                    case 'center':
+                        if (me.queryCommandValue('imagefloat') != 'center') {
+                            pN = img.parentNode;
+                            domUtils.setStyle(img, 'float', '');
+                            domUtils.removeAttributes(img,'align');
+                            tmpNode = img;
+                            while (pN && domUtils.getChildCount(pN, function (node) {
+                                return !domUtils.isBr(node) && !domUtils.isWhitespace(node);
+                            }) == 1
+                                && (dtd.$inline[pN.tagName] || pN.tagName == 'A')) {
+                                tmpNode = pN;
+                                pN = pN.parentNode;
+                            }
+                            range.setStartBefore(tmpNode).setCursor(false);
+                            pN = me.document.createElement('div');
+                            pN.appendChild(tmpNode);
+                            domUtils.setStyle(tmpNode, 'float', '');
+
+                            me.execCommand('insertHtml', '<p id="_img_parent_tmp" style="text-align:center">' + pN.innerHTML + '</p>');
+
+                            tmpNode = me.document.getElementById('_img_parent_tmp');
+                            tmpNode.removeAttribute('id');
+                            tmpNode = tmpNode.firstChild;
+                            range.selectNode(tmpNode).select();
+                            //去掉后边多余的元素
+                            next = tmpNode.parentNode.nextSibling;
+                            if (next && domUtils.isEmptyNode(next)) {
+                                domUtils.remove(next);
+                            }
+
+                        }
+
+                        break;
+                }
+
+            }
+        }
+    },
+    queryCommandValue:function () {
+        var range = this.selection.getRange(),
+            startNode, floatStyle;
+        if (range.collapsed) {
+            return 'none';
+        }
+        startNode = range.getClosedNode();
+        if (startNode && startNode.nodeType == 1 && startNode.tagName == 'IMG') {
+            floatStyle = startNode.getAttribute('align')||domUtils.getComputedStyle(startNode, 'float');
+            if (floatStyle == 'none') {
+                floatStyle = domUtils.getComputedStyle(startNode.parentNode, 'text-align') == 'center' ? 'center' : floatStyle;
+            }
+            return {
+                left:1,
+                right:1,
+                center:1
+            }[floatStyle] ? floatStyle : 'none';
+        }
+        return 'none';
+
+
+    },
+    queryCommandState:function () {
+        var range = this.selection.getRange(),
+            startNode;
+
+        if (range.collapsed)  return -1;
+
+        startNode = range.getClosedNode();
+        if (startNode && startNode.nodeType == 1 && startNode.tagName == 'IMG') {
+            return 0;
+        }
+        return -1;
+    }
+};
+
+UE.commands['insertimage'] = {
+    execCommand:function (cmd, opt) {
+
+        opt = utils.isArray(opt) ? opt : [opt];
+        if (!opt.length) {
+            return;
+        }
+        var me = this,
+            range = me.selection.getRange(),
+            img = range.getClosedNode();
+        if (img && /img/i.test(img.tagName) && img.className != "edui-faked-video" && !img.getAttribute("word_img")) {
+            var first = opt.shift();
+            var floatStyle = first['floatStyle'];
+            delete first['floatStyle'];
+////                img.style.border = (first.border||0) +"px solid #000";
+////                img.style.margin = (first.margin||0) +"px";
+//                img.style.cssText += ';margin:' + (first.margin||0) +"px;" + 'border:' + (first.border||0) +"px solid #000";
+            domUtils.setAttributes(img, first);
+            me.execCommand('imagefloat', floatStyle);
+            if (opt.length > 0) {
+                range.setStartAfter(img).setCursor(false, true);
+                me.execCommand('insertimage', opt);
+            }
+
+        } else {
+            var html = [], str = '', ci;
+            ci = opt[0];
+            if (opt.length == 1) {
+                str = '<img src="' + ci.src + '" ' + (ci.data_ue_src ? ' data_ue_src="' + ci.data_ue_src + '" ' : '') +
+                    (ci.width ? 'width="' + ci.width + '" ' : '') +
+                    (ci.height ? ' height="' + ci.height + '" ' : '') +
+                    (ci['floatStyle'] == 'left' || ci['floatStyle'] == 'right' ? ' style="float:' + ci['floatStyle'] + ';"' : '') +
+                    (ci.title && ci.title != "" ? ' title="' + ci.title + '"' : '') +
+                    (ci.border && ci.border != "0" ? ' border="' + ci.border + '"' : '') +
+                    (ci.alt && ci.alt != "" ? ' alt="' + ci.alt + '"' : '') +
+                    (ci.hspace && ci.hspace != "0" ? ' hspace = "' + ci.hspace + '"' : '') +
+                    (ci.vspace && ci.vspace != "0" ? ' vspace = "' + ci.vspace + '"' : '') + '/>';
+                if (ci['floatStyle'] == 'center') {
+                    str = '<p style="text-align: center">' + str + '</p>';
+                }
+                html.push(str);
+
+            } else {
+                for (var i = 0; ci = opt[i++];) {
+                    str = '<p ' + (ci['floatStyle'] == 'center' ? 'style="text-align: center" ' : '') + '><img src="' + ci.src + '" ' +
+                        (ci.width ? 'width="' + ci.width + '" ' : '') + (ci.data_ue_src ? ' data_ue_src="' + ci.data_ue_src + '" ' : '') +
+                        (ci.height ? ' height="' + ci.height + '" ' : '') +
+                        ' style="' + (ci['floatStyle'] && ci['floatStyle'] != 'center' ? 'float:' + ci['floatStyle'] + ';' : '') +
+                        (ci.border || '') + '" ' +
+                        (ci.title ? ' title="' + ci.title + '"' : '') + ' /></p>';
+                    html.push(str);
+                }
+            }
+
+            me.execCommand('insertHtml', html.join(''));
+        }
+    }
+};

+ 22 - 0
web/js/ueditor2/_src/plugins/indent.js

@@ -0,0 +1,22 @@
+///import core
+///import plugins\paragraph.js
+///commands 首行缩进
+///commandsName  Outdent,Indent
+///commandsTitle  取消缩进,首行缩进
+/**
+ * 首行缩进
+ * @function
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     outdent取消缩进,indent缩进
+ */
+UE.commands['indent'] = {
+    execCommand : function() {
+         var me = this,value = me.queryCommandState("indent") ? "0em" : (me.options.indentValue || '2em');
+         me.execCommand('Paragraph','p',{style:'text-indent:'+ value});
+    },
+    queryCommandState : function() {
+        var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),'p h1 h2 h3 h4 h5 h6');
+        return pN && pN.style.textIndent && parseInt(pN.style.textIndent) ?  1 : 0;
+    }
+
+};

+ 156 - 0
web/js/ueditor2/_src/plugins/inserthtml.js

@@ -0,0 +1,156 @@
+///import core
+/**
+ * @description 插入内容
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     inserthtml插入内容的命令
+ * @param   {String}   html                要插入的内容
+ * @author zhanyi
+ */
+UE.commands['inserthtml'] = {
+    execCommand: function (command,html,notSerialize){
+        var me = this,
+            range,
+            div;
+        if(!html){
+            return;
+        }
+        range = me.selection.getRange();
+        div = range.document.createElement( 'div' );
+        div.style.display = 'inline';
+        var serialize = me.serialize;
+        if (!notSerialize && serialize) {
+            var node = serialize.parseHTML(html);
+            node = serialize.transformInput(node);
+            node = serialize.filter(node);
+            html = serialize.toHTML(node);
+        }
+        div.innerHTML = utils.trim( html );
+
+        if ( !range.collapsed ) {
+            var tmpNode = range.startContainer;
+            if(domUtils.isFillChar(tmpNode)){
+                range.setStartBefore(tmpNode)
+            }
+            tmpNode = range.endContainer;
+            if(domUtils.isFillChar(tmpNode)){
+                range.setEndAfter(tmpNode)
+            }
+            range.txtToElmBoundary();
+            //结束边界可能放到了br的前边,要把br包含进来
+            // x[xxx]<br/>
+            if(range.endContainer && range.endContainer.nodeType == 1){
+                tmpNode = range.endContainer.childNodes[range.endOffset];
+                if(tmpNode && domUtils.isBr(tmpNode)){
+                    range.setEndAfter(tmpNode);
+                }
+            }
+            if(range.startOffset == 0){
+                tmpNode = range.startContainer;
+                if(domUtils.isBoundaryNode(tmpNode,'firstChild') ){
+                    tmpNode = range.endContainer;
+                    if(range.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode,'lastChild')){
+                        me.body.innerHTML = '<p>'+(browser.ie ? '' : '<br/>')+'</p>';
+                        range.setStart(me.body.firstChild,0).collapse(true)
+
+                    }
+                }
+            }
+            !range.collapsed && range.deleteContents();
+            if(range.startContainer.nodeType == 1){
+                var child = range.startContainer.childNodes[range.startOffset],pre;
+                if(child && domUtils.isBlockElm(child) && (pre = child.previousSibling) && domUtils.isBlockElm(pre)){
+                    range.setEnd(pre,pre.childNodes.length).collapse();
+                    while(child.firstChild){
+                        pre.appendChild(child.firstChild);
+                    }
+                    domUtils.remove(child);
+                }
+            }
+
+        }
+
+
+        var child,parent,pre,tmp,hadBreak = 0, nextNode;
+        //如果当前位置选中了fillchar要干掉,要不会产生空行
+        if(range.inFillChar()){
+            child = range.startContainer;
+            range.setStartBefore(child).collapse(true);
+            domUtils.remove(child);
+        }
+        while ( child = div.firstChild ) {
+            range.insertNode( child );
+            nextNode = child.nextSibling;
+            if ( !hadBreak && child.nodeType == domUtils.NODE_ELEMENT && domUtils.isBlockElm( child ) ){
+
+                parent = domUtils.findParent( child,function ( node ){ return domUtils.isBlockElm( node ); } );
+                if ( parent && parent.tagName.toLowerCase() != 'body' && !(dtd[parent.tagName][child.nodeName] && child.parentNode === parent)){
+                    if(!dtd[parent.tagName][child.nodeName]){
+                        pre = parent;
+                    }else{
+                        tmp = child.parentNode;
+                        while (tmp !== parent){
+                            pre = tmp;
+                            tmp = tmp.parentNode;
+
+                        }
+                    }
+
+
+                    domUtils.breakParent( child, pre || tmp );
+                    //去掉break后前一个多余的节点  <p>|<[p> ==> <p></p><div></div><p>|</p>
+                    var pre = child.previousSibling;
+                    domUtils.trimWhiteTextNode(pre);
+                    if(!pre.childNodes.length){
+                        domUtils.remove(pre);
+                    }
+                    //trace:2012,在非ie的情况,切开后剩下的节点有可能不能点入光标添加br占位
+
+                    if(!browser.ie &&
+                        (next = child.nextSibling) &&
+                        domUtils.isBlockElm(next) &&
+                        next.lastChild &&
+                        !domUtils.isBr(next.lastChild)){
+                        next.appendChild(me.document.createElement('br'));
+                    }
+                    hadBreak = 1;
+                }
+            }
+            var next = child.nextSibling;
+            if(!div.firstChild && next && domUtils.isBlockElm(next)){
+
+                range.setStart(next,0).collapse(true);
+                break;
+            }
+            range.setEndAfter( child ).collapse();
+
+        }
+
+        child = range.startContainer;
+
+        if(nextNode && domUtils.isBr(nextNode)){
+            domUtils.remove(nextNode)
+        }
+        //用chrome可能有空白展位符
+        if(domUtils.isBlockElm(child) && domUtils.isEmptyNode(child)){
+            if(nextNode = child.nextSibling){
+                domUtils.remove(child);
+                if(nextNode.nodeType == 1 && dtd.$block[nextNode.tagName]){
+
+                    range.setStart(nextNode,0).collapse(true).shrinkBoundary()
+                }
+            }else{
+                child.innerHTML = browser.ie ? domUtils.fillChar : '<br/>';
+            }
+
+        }
+        //加上true因为在删除表情等时会删两次,第一次是删的fillData
+        range.select(true);
+
+
+        setTimeout(function(){
+            range = me.selection.getRange();
+            range.scrollToView(me.autoHeightEnabled,me.autoHeightEnabled ? domUtils.getXY(me.iframe).y:0);
+            me.fireEvent('afterinserthtml');
+        },200);
+    }
+};

+ 36 - 0
web/js/ueditor2/_src/plugins/insertparagraph.js

@@ -0,0 +1,36 @@
+///import core
+///commands 插入空行
+///commandsName  insertparagraph
+///commandsTitle  插入空行
+/**
+ * 插入空行
+ * @function
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     insertparagraph
+ */
+
+UE.commands['insertparagraph'] = {
+    execCommand : function( cmdName,front) {
+        var me = this,
+            range = me.selection.getRange(),
+            start = range.startContainer,tmpNode;
+        while(start ){
+            if(domUtils.isBody(start)){
+                break;
+            }
+            tmpNode = start;
+            start = start.parentNode;
+        }
+        if(tmpNode){
+            var p = me.document.createElement('p');
+            if(front){
+                tmpNode.parentNode.insertBefore(p,tmpNode)
+            }else{
+                tmpNode.parentNode.insertBefore(p,tmpNode.nextSibling)
+            }
+            domUtils.fillNode(me.document,p);
+            range.setStart(p,0).setCursor(false,true);
+        }
+    }
+};
+

+ 93 - 0
web/js/ueditor2/_src/plugins/justify.js

@@ -0,0 +1,93 @@
+///import core
+///commands 段落格式,居左,居右,居中,两端对齐
+///commandsName  JustifyLeft,JustifyCenter,JustifyRight,JustifyJustify
+///commandsTitle  居左对齐,居中对齐,居右对齐,两端对齐
+/**
+ * @description 居左右中
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     justify执行对齐方式的命令
+ * @param   {String}   align               对齐方式:left居左,right居右,center居中,justify两端对齐
+ * @author zhanyi
+ */
+UE.plugins['justify']=function(){
+    var me=this,
+        block = domUtils.isBlockElm,
+        defaultValue = {
+            left:1,
+            right:1,
+            center:1,
+            justify:1
+        },
+        doJustify = function (range, style) {
+            var bookmark = range.createBookmark(),
+                filterFn = function (node) {
+                    return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' && !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace(node);
+                };
+
+            range.enlarge(true);
+            var bookmark2 = range.createBookmark(),
+                current = domUtils.getNextDomNode(bookmark2.start, false, filterFn),
+                tmpRange = range.cloneRange(),
+                tmpNode;
+            while (current && !(domUtils.getPosition(current, bookmark2.end) & domUtils.POSITION_FOLLOWING)) {
+                if (current.nodeType == 3 || !block(current)) {
+                    tmpRange.setStartBefore(current);
+                    while (current && current !== bookmark2.end && !block(current)) {
+                        tmpNode = current;
+                        current = domUtils.getNextDomNode(current, false, null, function (node) {
+                            return !block(node);
+                        });
+                    }
+                    tmpRange.setEndAfter(tmpNode);
+                    var common = tmpRange.getCommonAncestor();
+                    if (!domUtils.isBody(common) && block(common)) {
+                        domUtils.setStyles(common, utils.isString(style) ? {'text-align':style} : style);
+                        current = common;
+                    } else {
+                        var p = range.document.createElement('p');
+                        domUtils.setStyles(p, utils.isString(style) ? {'text-align':style} : style);
+                        var frag = tmpRange.extractContents();
+                        p.appendChild(frag);
+                        tmpRange.insertNode(p);
+                        current = p;
+                    }
+                    current = domUtils.getNextDomNode(current, false, filterFn);
+                } else {
+                    current = domUtils.getNextDomNode(current, true, filterFn);
+                }
+            }
+            return range.moveToBookmark(bookmark2).moveToBookmark(bookmark);
+        };
+
+    UE.commands['justify'] = {
+        execCommand:function (cmdName, align) {
+            var range = this.selection.getRange(),
+                txt;
+
+            //闭合时单独处理
+            if (range.collapsed) {
+                txt = this.document.createTextNode('p');
+                range.insertNode(txt);
+            }
+            doJustify(range, align);
+            if (txt) {
+                range.setStartBefore(txt).collapse(true);
+                domUtils.remove(txt);
+            }
+
+            range.select();
+
+
+            return true;
+        },
+        queryCommandValue:function () {
+            var startNode = this.selection.getStart(),
+                value = domUtils.getComputedStyle(startNode, 'text-align');
+            return defaultValue[value] ? value : 'left';
+        },
+        queryCommandState:function () {
+        	return this.highlight ? -1 : 0;
+        }
+
+    };
+};

+ 166 - 0
web/js/ueditor2/_src/plugins/keystrokes.js

@@ -0,0 +1,166 @@
+/*
+ *   处理特殊键的兼容性问题
+ */
+UE.plugins['keystrokes'] = function() {
+    var me = this;
+
+    me.addListener('keydown', function(type, evt) {
+        var keyCode = evt.keyCode || evt.which,
+            rng = me.selection.getRange();
+
+        //处理全选的情况
+        if(!rng.collapsed && !(evt.ctrlKey || evt.metaKey || evt.shiftKey || evt.altKey || keyCode == 9 )){
+
+            var tmpNode = rng.startContainer;
+            if(domUtils.isFillChar(tmpNode)){
+                rng.setStartBefore(tmpNode)
+            }
+            tmpNode = rng.endContainer;
+            if(domUtils.isFillChar(tmpNode)){
+                rng.setEndAfter(tmpNode)
+            }
+            rng.txtToElmBoundary();
+            //结束边界可能放到了br的前边,要把br包含进来
+            // x[xxx]<br/>
+            if(rng.endContainer && rng.endContainer.nodeType == 1){
+                tmpNode = rng.endContainer.childNodes[rng.endOffset];
+                if(tmpNode && domUtils.isBr(tmpNode)){
+                    rng.setEndAfter(tmpNode);
+                }
+            }
+            if(rng.startOffset == 0){
+                tmpNode = rng.startContainer;
+                if(domUtils.isBoundaryNode(tmpNode,'firstChild') ){
+                    tmpNode = rng.endContainer;
+                    if(rng.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode,'lastChild')){
+                        me.fireEvent('saveScene');
+                        me.body.innerHTML = '<p>'+(browser.ie ? '' : '<br/>')+'</p>';
+                        rng.setStart(me.body.firstChild,0).setCursor(false,true);
+                        browser.ie && me._selectionChange();
+                        domUtils.preventDefault(evt);
+                        return;
+                    }
+                }
+            }
+        }
+
+
+        //处理backspace/del
+        if (keyCode == 8) {//|| keyCode == 46
+            var start,end;
+            //避免按两次删除才能生效的问题
+            if(rng.inFillChar()){
+                start = rng.startContainer;
+                rng.setStartBefore(start).shrinkBoundary(true).collapse(true);
+                if(domUtils.isFillChar(start)){
+                    domUtils.remove(start)
+                }else{
+                    start.nodeValue = start.nodeValue.replace(new RegExp('^' + domUtils.fillChar ),'');
+                }
+            }
+
+            //解决选中control元素不能删除的问题
+            if (start = rng.getClosedNode()) {
+                me.fireEvent('saveScene');
+                rng.setStartBefore(start);
+                domUtils.remove(start);
+                rng.setCursor();
+                me.fireEvent('saveScene');
+                domUtils.preventDefault(evt);
+                return;
+            }
+            //阻止在table上的删除
+            if (!browser.ie) {
+                start = domUtils.findParentByTagName(rng.startContainer, 'table', true);
+                end = domUtils.findParentByTagName(rng.endContainer, 'table', true);
+                if (start && !end || !start && end || start !== end) {
+                    evt.preventDefault();
+                    return;
+                }
+            }
+        }
+        //处理tab键的逻辑
+        if (keyCode == 9) {
+            //不处理以下标签
+            var excludeTagNameForTabKey = {
+                'ol' : 1,
+                'ul' : 1,
+                'table':1
+            };
+            //处理组件里的tab按下事件
+            if(me.fireEvent('tabkeydown')){
+                domUtils.preventDefault(evt);
+                return;
+            }
+            range = me.selection.getRange();
+            me.fireEvent('saveScene');
+            for (var i = 0,txt = '',tabSize = me.options.tabSize|| 4,tabNode =  me.options.tabNode || '&nbsp;'; i < tabSize; i++) {
+                txt += tabNode;
+            }
+            var span = me.document.createElement('span');
+            span.innerHTML = txt + domUtils.fillChar;
+            if (range.collapsed) {
+                range.insertNode(span.cloneNode(true).firstChild).setCursor(true);
+            } else {
+                //普通的情况
+                start = domUtils.findParent(range.startContainer, filterFn);
+                end = domUtils.findParent(range.endContainer, filterFn);
+                if (start && end && start === end) {
+                    range.deleteContents();
+                    range.insertNode(span.cloneNode(true).firstChild).setCursor(true);
+                } else {
+                    var bookmark = range.createBookmark(),
+                        filterFn = function(node) {
+                            return domUtils.isBlockElm(node) && !excludeTagNameForTabKey[node.tagName.toLowerCase()]
+
+                        };
+                    range.enlarge(true);
+                    var bookmark2 = range.createBookmark(),
+                        current = domUtils.getNextDomNode(bookmark2.start, false, filterFn);
+                    while (current && !(domUtils.getPosition(current, bookmark2.end) & domUtils.POSITION_FOLLOWING)) {
+                        current.insertBefore(span.cloneNode(true).firstChild, current.firstChild);
+                        current = domUtils.getNextDomNode(current, false, filterFn);
+                    }
+                    range.moveToBookmark(bookmark2).moveToBookmark(bookmark).select();
+                }
+            }
+            domUtils.preventDefault(evt)
+        }
+        //trace:1634
+        //ff的del键在容器空的时候,也会删除
+        if(browser.gecko && keyCode == 46){
+            range = me.selection.getRange();
+            if(range.collapsed){
+                start = range.startContainer;
+                if(domUtils.isEmptyBlock(start)){
+                    var parent = start.parentNode;
+                    while(domUtils.getChildCount(parent) == 1 && !domUtils.isBody(parent)){
+                        start = parent;
+                        parent = parent.parentNode;
+                    }
+                    if(start === parent.lastChild)
+                        evt.preventDefault();
+                    return;
+                }
+            }
+        }
+    });
+    me.addListener('keyup', function(type, evt) {
+        var keyCode = evt.keyCode || evt.which,
+            rng;
+        if(keyCode == 8){
+            rng = me.selection.getRange();
+            //处理当删除到body时,要重新给p标签展位
+            if(rng.collapsed && domUtils.isBody(rng.startContainer)){
+                var tmpNode = domUtils.createElement(me.document,'p',{
+                    'innerHTML' : browser.ie ? domUtils.fillChar : '<br/>'
+                });
+                rng.insertNode(tmpNode).setStart(tmpNode,0).setCursor(false,true);
+            }
+//            //chrome下如果删除了inline标签,浏览器会有记忆,在输入文字还是会套上刚才删除的标签,所以这里再选一次就不会了
+            if(browser.chrome && rng.collapsed && rng.startContainer.nodeType == 1 && domUtils.isEmptyBlock(rng.startContainer)){
+                rng.select(true);
+            }
+        }
+    })
+};

+ 31 - 0
web/js/ueditor2/_src/plugins/lineheight.js

@@ -0,0 +1,31 @@
+///import core
+///import plugins\paragraph.js
+///commands 行间距
+///commandsName  LineHeight
+///commandsTitle  行间距
+/**
+ * @description 设置行内间距
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     lineheight设置行内间距
+ * @param   {String}   value              值
+ * @author zhuwenxuan
+ */
+UE.plugins['lineheight'] = function(){
+    var me = this;
+    me.setOpt({'lineheight':['1', '1.5','1.75','2', '3', '4', '5']});
+    me.commands['lineheight'] =  {
+        execCommand : function( cmdName,value ) {
+            this.execCommand('paragraph','p',{style:'line-height:'+ (value == "1" ? "normal" : value + 'em') });
+            return true;
+        },
+        queryCommandValue : function() {
+            var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),function(node){return domUtils.isBlockElm(node)});
+            if(pN){
+                var value = domUtils.getComputedStyle(pN,'line-height');
+                return value == 'normal' ? 1 : value.replace(/[^\d.]*/ig,"");
+            }
+        }
+    };
+};
+
+

+ 153 - 0
web/js/ueditor2/_src/plugins/link.js

@@ -0,0 +1,153 @@
+///import core
+///commands 超链接,取消链接
+///commandsName  Link,Unlink
+///commandsTitle  超链接,取消链接
+///commandsDialog  dialogs\link
+/**
+ * 超链接
+ * @function
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     link插入超链接
+ * @param   {Object}  options         url地址,title标题,target是否打开新页
+ * @author zhanyi
+ */
+/**
+ * 取消链接
+ * @function
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     unlink取消链接
+ * @author zhanyi
+ */
+(function() {
+    function optimize( range ) {
+        var start = range.startContainer,end = range.endContainer;
+
+        if ( start = domUtils.findParentByTagName( start, 'a', true ) ) {
+            range.setStartBefore( start );
+        }
+        if ( end = domUtils.findParentByTagName( end, 'a', true ) ) {
+            range.setEndAfter( end );
+        }
+    }
+
+
+    UE.commands['unlink'] = {
+        execCommand : function() {
+            var range = this.selection.getRange(),
+                bookmark;
+            if(range.collapsed && !domUtils.findParentByTagName( range.startContainer, 'a', true )){
+                return;
+            }
+            bookmark = range.createBookmark();
+            optimize( range );
+            range.removeInlineStyle( 'a' ).moveToBookmark( bookmark ).select();
+        },
+        queryCommandState : function(){
+            return !this.highlight && this.queryCommandValue('link') ?  0 : -1;
+        }
+
+    };
+    function doLink(range,opt,me){
+        var rngClone = range.cloneRange(),
+            link = me.queryCommandValue('link');
+        optimize( range = range.adjustmentBoundary() );
+        var start = range.startContainer;
+        if(start.nodeType == 1 && link){
+            start = start.childNodes[range.startOffset];
+            if(start && start.nodeType == 1 && start.tagName == 'A' && /^(?:https?|ftp|file)\s*:\s*\/\//.test(start[browser.ie?'innerText':'textContent'])){
+                start[browser.ie ? 'innerText' : 'textContent'] =  utils.html(opt.textValue||opt.href);
+
+            }
+        }
+        if( !rngClone.collapsed || link){
+            range.removeInlineStyle( 'a' );
+            rngClone = range.cloneRange();
+        }
+
+        if ( rngClone.collapsed ) {
+            var a = range.document.createElement( 'a'),
+                text = '';
+            if(opt.textValue){
+
+                text =   utils.html(opt.textValue);
+                delete opt.textValue;
+            }else{
+                text =   utils.html(opt.href);
+
+            }
+            domUtils.setAttributes( a, opt );
+            start =  domUtils.findParentByTagName( rngClone.startContainer, 'a', true );
+            if(start && domUtils.isInNodeEndBoundary(rngClone,start)){
+                range.setStartAfter(start).collapse(true);
+
+            }
+            a[browser.ie ? 'innerText' : 'textContent'] = text;
+            range.insertNode(a).selectNode( a );
+        } else {
+            range.applyInlineStyle( 'a', opt );
+
+        }
+    }
+    UE.commands['link'] = {
+        execCommand : function( cmdName, opt ) {
+            var range;
+            opt.data_ue_src && (opt.data_ue_src = utils.unhtml(opt.data_ue_src,/[<">]/g));
+            opt.href && (opt.href = utils.unhtml(opt.href,/[<">]/g));
+            opt.textValue && (opt.textValue = utils.unhtml(opt.textValue,/[<">]/g));
+            doLink(range=this.selection.getRange(),opt,this);
+            //闭合都不加占位符,如果加了会在a后边多个占位符节点,导致a是图片背景组成的列表,出现空白问题
+            range.collapse().select(true);
+
+        },
+        queryCommandValue : function() {
+            var range = this.selection.getRange(),
+                node;
+
+
+
+            if ( range.collapsed ) {
+//                    node = this.selection.getStart();
+                //在ie下getstart()取值偏上了
+                node = range.startContainer;
+                node = node.nodeType == 1 ? node : node.parentNode;
+
+                if ( node && (node = domUtils.findParentByTagName( node, 'a', true )) && ! domUtils.isInNodeEndBoundary(range,node)) {
+
+                    return node;
+                }
+            } else {
+                //trace:1111  如果是<p><a>xx</a></p> startContainer是p就会找不到a
+                range.shrinkBoundary();
+                var start = range.startContainer.nodeType  == 3 || !range.startContainer.childNodes[range.startOffset] ? range.startContainer : range.startContainer.childNodes[range.startOffset],
+                    end =  range.endContainer.nodeType == 3 || range.endOffset == 0 ? range.endContainer : range.endContainer.childNodes[range.endOffset-1],
+                    common = range.getCommonAncestor();
+                node = domUtils.findParentByTagName( common, 'a', true );
+                if ( !node && common.nodeType == 1){
+
+                    var as = common.getElementsByTagName( 'a' ),
+                        ps,pe;
+
+                    for ( var i = 0,ci; ci = as[i++]; ) {
+                        ps = domUtils.getPosition( ci, start ),pe = domUtils.getPosition( ci,end);
+                        if ( (ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS)
+                            &&
+                            (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS)
+                            ) {
+                            node = ci;
+                            break;
+                        }
+                    }
+                }
+                return node;
+            }
+
+        },
+        queryCommandState : function() {
+            //判断如果是视频的话连接不可用
+            //fix 853
+            var img = this.selection.getRange().getClosedNode(),
+                flag = img && (img.className == "edui-faked-video");
+            return flag ? -1 : 0;
+        }
+    };
+})();

+ 910 - 0
web/js/ueditor2/_src/plugins/list.js

@@ -0,0 +1,910 @@
+///import core
+///commands 有序列表,无序列表
+///commandsName  InsertOrderedList,InsertUnorderedList
+///commandsTitle  有序列表,无序列表
+/**
+ * 有序列表
+ * @function
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     insertorderlist插入有序列表
+ * @param   {String}   style               值为:decimal,lower-alpha,lower-roman,upper-alpha,upper-roman
+ * @author zhanyi
+ */
+/**
+ * 无序链接
+ * @function
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     insertunorderlist插入无序列表
+ * * @param   {String}   style            值为:circle,disc,square
+ * @author zhanyi
+ */
+
+UE.plugins['list'] = function () {
+    var me = this,
+        notExchange = {
+            'TD':1,
+            'PRE':1,
+            'BLOCKQUOTE':1
+        };
+    var customStyle = {
+        'cn' : 'cn-1-',
+        'cn1' : 'cn-2-',
+        'cn2' : 'cn-3-',
+        'num':  'num-1-',
+        'num1' : 'num-2-',
+        'num2' : 'num-3-',
+        'dash'  : 'dash',
+        'dot':'dot'
+    };
+
+    me.setOpt( {
+        'insertorderedlist':{
+            'num':'',
+            'num1':'',
+            'num2':'',
+            'cn':'',
+            'cn1':'',
+            'cn2':'',
+            'decimal':'',
+            'lower-alpha':'',
+            'lower-roman':'',
+            'upper-alpha':'',
+            'upper-roman':''
+        },
+        'insertunorderedlist':{
+            'circle':'',
+            'disc':'',
+            'square':'',
+            'dash' : '',
+            'dot':''
+        },
+        listDefaultPaddingLeft : '30',
+        listiconpath : 'http://bs.baidu.com/listicon/',
+        maxListLevel : 3//-1不限制
+    } );
+    var liiconpath = me.options.listiconpath;
+
+    //根据用户配置,调整customStyle
+    for(var s in customStyle){
+        if(!me.options.insertorderedlist.hasOwnProperty(s) && !me.options.insertunorderedlist.hasOwnProperty(s)){
+            delete customStyle[s];
+        }
+    }
+
+    me.ready(function () {
+        var customCss = [];
+        for(var p in customStyle){
+            if(p == 'dash' || p == 'dot'){
+                customCss.push('li.list-' + customStyle[p] + '{background-image:url(' + liiconpath +customStyle[p]+'.gif)}');
+                customCss.push('ul.custom_'+p+'{list-style:none;}ul.custom_'+p+' li{background-position:0 3px;background-repeat:no-repeat}');
+            }else{
+                for(var i= 0;i<99;i++){
+                    customCss.push('li.list-' + customStyle[p] + i + '{background-image:url(' + liiconpath + 'list-'+customStyle[p] + i + '.gif)}')
+                }
+                customCss.push('ol.custom_'+p+'{list-style:none;}ol.custom_'+p+' li{background-position:0 3px;background-repeat:no-repeat}');
+            }
+            switch(p){
+                case 'cn':
+                    customCss.push('li.list-'+p+'-paddingleft-1{padding-left:25px}');
+                    customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}');
+                    customCss.push('li.list-'+p+'-paddingleft-3{padding-left:55px}');
+                    break;
+                case 'cn1':
+                    customCss.push('li.list-'+p+'-paddingleft-1{padding-left:30px}');
+                    customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}');
+                    customCss.push('li.list-'+p+'-paddingleft-3{padding-left:55px}');
+                    break;
+                case 'cn2':
+                    customCss.push('li.list-'+p+'-paddingleft-1{padding-left:40px}');
+                    customCss.push('li.list-'+p+'-paddingleft-2{padding-left:55px}');
+                    customCss.push('li.list-'+p+'-paddingleft-3{padding-left:68px}');
+                    break;
+                case 'num':
+                case 'num1':
+                    customCss.push('li.list-'+p+'-paddingleft-1{padding-left:25px}');
+                    break;
+                case 'num2':
+                    customCss.push('li.list-'+p+'-paddingleft-1{padding-left:35px}');
+                    customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}');
+                    break;
+                case 'dash':
+                    customCss.push('li.list-'+p+'-paddingleft{padding-left:35px}');
+                    break;
+                case 'dot':
+                    customCss.push('li.list-'+p+'-paddingleft{padding-left:20px}');
+            }
+        }
+        customCss.push('.list-paddingleft-1{padding-left:0}');
+        customCss.push('.list-paddingleft-2{padding-left:'+me.options.listDefaultPaddingLeft+'px}');
+        customCss.push('.list-paddingleft-3{padding-left:'+me.options.listDefaultPaddingLeft*2+'px}');
+        //如果不给宽度会在自定应样式里出现滚动条
+        utils.cssRule('list', 'ol,ul{margin:0;pading:0;'+(browser.ie ? '' : 'width:95%')+'}li{clear:both;}'+customCss.join('\n'), me.document);
+    });
+
+    function getStyle(node){
+        var cls = node.className;
+        if(domUtils.hasClass(node,/custom_/)){
+            return cls.match(/custom_(\w+)/)[1]
+        }
+        return ''
+    }
+
+//    function checkCustomStyle(list){
+//        if(domUtils.hasClass(list,/custom_/)){
+//            return ''
+//        }
+//        var style;
+//        utils.each(list.childNodes,function(li){
+//            if(li.tagName == 'LI'){
+//                if(domUtils.hasClass(li,/list-/)){
+//                    var tmpStyle = li.className.match(/list-(\w+)-(\d+)?/);
+//                    style = tmpStyle[1]+(tmpStyle[2] && tmpStyle[2] != '1'?  tmpStyle[2]:'');
+//                    return false
+//                }
+//            }
+//        })
+//        return style;
+//    }
+    //调整索引标签
+    me.addListener('contentchange',function(){
+        utils.each(domUtils.getElementsByTagName(me.document,'ol ul'),function(node){
+
+            if(!domUtils.inDoc(node,me.document))
+                return;
+//            var style;
+//            if(style = checkCustomStyle(node)){
+//                node.className = 'custom_' + style;
+//            }
+            var index = 0,type = 2,parent = node.parentNode;
+            if( domUtils.hasClass(node,/custom_/)){
+                if(!(/[ou]l/i.test(parent.tagName) && domUtils.hasClass(parent,/custom_/))){
+                    type = 1;
+                }
+            }else{
+                if(/[ou]l/i.test(parent.tagName) && domUtils.hasClass(parent,/custom_/)){
+                    type = 3;
+                }
+            }
+            style = domUtils.getStyle(node, 'list-style-type');
+            node.style.cssText = style ? 'list-style-type:' + style : '';
+            node.className = utils.trim(node.className.replace(/list-paddingleft-\w+/,'')) + ' list-paddingleft-' + type;
+            utils.each(domUtils.getElementsByTagName(node,'li'),function(li){
+                li.style.cssText && (li.style.cssText = '');
+                if(!li.firstChild){
+                    domUtils.remove(li);
+                    return;
+                }
+                if(li.parentNode !== node){
+                    return;
+                }
+                index++;
+                if(domUtils.hasClass(node,/custom_/) ){
+                    var paddingLeft = 1,currentStyle = getStyle(node);
+                    if(node.tagName == 'OL'){
+                        if(currentStyle){
+                            switch(currentStyle){
+                                case 'cn' :
+                                case 'cn1':
+                                case 'cn2':
+                                    if(index > 10 && (index % 10 == 0 || index > 10 && index < 20)){
+                                        paddingLeft = 2
+                                    }else if(index > 20){
+                                        paddingLeft = 3
+                                    }
+                                    break;
+                                case 'num2' :
+                                    if(index > 9){
+                                        paddingLeft = 2
+                                    }
+                            }
+                        }
+                        li.className = 'list-'+customStyle[currentStyle]+ index + ' ' + 'list-'+currentStyle+'-paddingleft-' + paddingLeft;
+                    }else{
+                        li.className = 'list-'+customStyle[currentStyle]  + ' ' + 'list-'+currentStyle+'-paddingleft';
+                    }
+                }else{
+                    li.className = li.className.replace(/list-[\w\-]+/gi,'');
+                }
+                var className = li.getAttribute('class');
+                if(className !== null && !className.replace(/\s/g,'')){
+                    domUtils.removeAttributes(li,'class')
+                }
+            });
+            adjustList(node,node.tagName.toLowerCase(),getStyle(node)||domUtils.getStyle(node, 'list-style-type'),true)
+        })
+    });
+
+
+    function adjustList(list, tag, style,ignoreEmpty) {
+        var nextList = list.nextSibling;
+        if (nextList && nextList.nodeType == 1 && nextList.tagName.toLowerCase() == tag && (getStyle(nextList) || domUtils.getStyle(nextList, 'list-style-type') || (tag == 'ol' ? 'decimal' : 'disc')) == style) {
+            domUtils.moveChild(nextList, list);
+            if (nextList.childNodes.length == 0) {
+                domUtils.remove(nextList);
+            }
+        }
+        if(nextList && domUtils.isFillChar(nextList)){
+            domUtils.remove(nextList);
+        }
+        var preList = list.previousSibling;
+        if (preList && preList.nodeType == 1 && preList.tagName.toLowerCase() == tag && (getStyle(preList) || domUtils.getStyle(preList, 'list-style-type') || (tag == 'ol' ? 'decimal' : 'disc')) == style) {
+            domUtils.moveChild(list, preList);
+        }
+        if(preList && domUtils.isFillChar(preList)){
+            domUtils.remove(preList);
+        }
+        !ignoreEmpty && domUtils.isEmptyBlock(list) && domUtils.remove(list);
+    }
+
+    function setListStyle(list,style){
+        if(customStyle[style]){
+            list.className = 'custom_' + style;
+        }
+        try{
+            domUtils.setStyle(list, 'list-style-type', style);
+        }catch(e){}
+    }
+    function clearEmptySibling(node) {
+        var tmpNode = node.previousSibling;
+        if (tmpNode && domUtils.isEmptyBlock(tmpNode)) {
+            domUtils.remove(tmpNode);
+        }
+        tmpNode = node.nextSibling;
+        if (tmpNode && domUtils.isEmptyBlock(tmpNode)) {
+            domUtils.remove(tmpNode);
+        }
+    }
+
+    me.addListener('keydown', function (type, evt) {
+        function preventAndSave() {
+            evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false);
+            me.fireEvent('contentchange');
+            me.undoManger && me.undoManger.save();
+        }
+        function findList(node,filterFn){
+            while(node && !domUtils.isBody(node)){
+                if(filterFn(node)){
+                    return null
+                }
+                if(node.nodeType == 1 && /[ou]l/i.test(node.tagName)){
+                    return node;
+                }
+                node = node.parentNode;
+            }
+            return null;
+        }
+        var keyCode = evt.keyCode || evt.which;
+        if (keyCode == 13 && !evt.shiftKey) {//回车
+            var range = me.selection.getRange(),
+                start = findList(range.startContainer,function (node) {
+                    return node.tagName == 'TABLE';
+                }),
+                end = range.collapsed ? start : findList(range.endContainer,function (node) {
+                    return node.tagName == 'TABLE';
+                });
+
+            if (start && end && start === end) {
+
+                if (!range.collapsed) {
+                    start = domUtils.findParentByTagName(range.startContainer, 'li', true);
+                    end = domUtils.findParentByTagName(range.endContainer, 'li', true);
+                    if (start && end && start === end) {
+                        range.deleteContents();
+                        li = domUtils.findParentByTagName(range.startContainer, 'li', true);
+                        if (li && domUtils.isEmptyBlock(li)) {
+
+                            pre = li.previousSibling;
+                            next = li.nextSibling;
+                            p = me.document.createElement('p');
+
+                            domUtils.fillNode(me.document, p);
+                            parentList = li.parentNode;
+                            if (pre && next) {
+                                range.setStart(next, 0).collapse(true).select(true);
+                                domUtils.remove(li);
+
+                            } else {
+                                if (!pre && !next || !pre) {
+
+                                    parentList.parentNode.insertBefore(p, parentList);
+
+
+                                } else {
+                                    li.parentNode.parentNode.insertBefore(p, parentList.nextSibling);
+                                }
+                                domUtils.remove(li);
+                                if (!parentList.firstChild) {
+                                    domUtils.remove(parentList);
+                                }
+                                range.setStart(p, 0).setCursor();
+
+
+                            }
+                            preventAndSave();
+                            return;
+
+                        }
+                    } else {
+                        var tmpRange = range.cloneRange(),
+                            bk = tmpRange.collapse(false).createBookmark();
+
+                        range.deleteContents();
+                        tmpRange.moveToBookmark(bk);
+                        var li = domUtils.findParentByTagName(tmpRange.startContainer, 'li', true);
+
+                        clearEmptySibling(li);
+                        tmpRange.select();
+                        preventAndSave();
+                        return;
+                    }
+                }
+
+
+                li = domUtils.findParentByTagName(range.startContainer, 'li', true);
+
+                if (li) {
+                    if (domUtils.isEmptyBlock(li)) {
+                        bk = range.createBookmark();
+                        var parentList = li.parentNode;
+                        if (li !== parentList.lastChild) {
+                            domUtils.breakParent(li, parentList);
+                            clearEmptySibling(li);
+                        } else {
+
+                            parentList.parentNode.insertBefore(li, parentList.nextSibling);
+                            if (domUtils.isEmptyNode(parentList)) {
+                                domUtils.remove(parentList);
+                            }
+                        }
+                        //嵌套不处理
+                        if (!dtd.$list[li.parentNode.tagName]) {
+
+                            if (!domUtils.isBlockElm(li.firstChild)) {
+                                p = me.document.createElement('p');
+                                li.parentNode.insertBefore(p, li);
+                                while (li.firstChild) {
+                                    p.appendChild(li.firstChild);
+                                }
+                                domUtils.remove(li);
+                            } else {
+                                domUtils.remove(li, true);
+                            }
+                        }
+                        range.moveToBookmark(bk).select();
+
+
+                    } else {
+                        var first = li.firstChild;
+                        if (!first || !domUtils.isBlockElm(first)) {
+                            var p = me.document.createElement('p');
+
+                            !li.firstChild && domUtils.fillNode(me.document, p);
+                            while (li.firstChild) {
+
+                                p.appendChild(li.firstChild);
+                            }
+                            li.appendChild(p);
+                            first = p;
+                        }
+
+                        var span = me.document.createElement('span');
+
+                        range.insertNode(span);
+                        domUtils.breakParent(span, li);
+
+                        var nextLi = span.nextSibling;
+                        first = nextLi.firstChild;
+
+                        if (!first) {
+                            p = me.document.createElement('p');
+
+                            domUtils.fillNode(me.document, p);
+                            nextLi.appendChild(p);
+                            first = p;
+                        }
+                        if (domUtils.isEmptyNode(first)) {
+                            first.innerHTML = '';
+                            domUtils.fillNode(me.document, first);
+                        }
+
+                        range.setStart(first, 0).collapse(true).shrinkBoundary().select();
+                        domUtils.remove(span);
+                        var pre = nextLi.previousSibling;
+                        if (pre && domUtils.isEmptyBlock(pre)) {
+                            pre.innerHTML = '<p></p>';
+                            domUtils.fillNode(me.document, pre.firstChild);
+                        }
+
+                    }
+//                        }
+                    preventAndSave();
+                }
+
+
+            }
+        }
+        if (keyCode == 8) {
+
+            //修中ie中li下的问题
+            range = me.selection.getRange();
+            if (range.collapsed && domUtils.isStartInblock(range)) {
+                tmpRange = range.cloneRange().trimBoundary();
+                li = domUtils.findParentByTagName(range.startContainer, 'li', true);
+                //要在li的最左边,才能处理
+                if (li && domUtils.isStartInblock(tmpRange)) {
+                    start = domUtils.findParentByTagName(range.startContainer, 'p', true);
+                    if (start && start !== li.firstChild) {
+                        var parentList = domUtils.findParentByTagName(start,['ol','ul']);
+                        domUtils.breakParent(start,parentList);
+                        clearEmptySibling(start);
+                        me.fireEvent('contentchange');
+                        range.setStart(start,0).setCursor(false,true);
+                        me.fireEvent('saveScene');
+                        domUtils.preventDefault(evt);
+                        return;
+                    }
+
+                    if (li && (pre = li.previousSibling)) {
+                        if (keyCode == 46 && li.childNodes.length) {
+                            return;
+                        }
+                        //有可能上边的兄弟节点是个2级菜单,要追加到2级菜单的最后的li
+                        if (dtd.$list[pre.tagName]) {
+                            pre = pre.lastChild;
+                        }
+                        me.undoManger && me.undoManger.save();
+                        first = li.firstChild;
+                        if (domUtils.isBlockElm(first)) {
+                            if (domUtils.isEmptyNode(first)) {
+//                                    range.setEnd(pre, pre.childNodes.length).shrinkBoundary().collapse().select(true);
+                                pre.appendChild(first);
+                                range.setStart(first, 0).setCursor(false, true);
+                                //first不是唯一的节点
+                                while (li.firstChild) {
+                                    pre.appendChild(li.firstChild);
+                                }
+                            } else {
+
+                                span = me.document.createElement('span');
+                                range.insertNode(span);
+                                //判断pre是否是空的节点,如果是<p><br/></p>类型的空节点,干掉p标签防止它占位
+                                if (domUtils.isEmptyBlock(pre)) {
+                                    pre.innerHTML = '';
+                                }
+                                domUtils.moveChild(li, pre);
+                                range.setStartBefore(span).collapse(true).select(true);
+
+                                domUtils.remove(span);
+
+                            }
+                        } else {
+                            if (domUtils.isEmptyNode(li)) {
+                                var p = me.document.createElement('p');
+                                pre.appendChild(p);
+                                range.setStart(p, 0).setCursor();
+//                                    range.setEnd(pre, pre.childNodes.length).shrinkBoundary().collapse().select(true);
+                            } else {
+                                range.setEnd(pre, pre.childNodes.length).collapse().select(true);
+                                while (li.firstChild) {
+                                    pre.appendChild(li.firstChild);
+                                }
+                            }
+                        }
+                        domUtils.remove(li);
+                        me.fireEvent('contentchange');
+                        me.fireEvent('saveScene');
+                        domUtils.preventDefault(evt);
+                        return;
+
+                    }
+                    //trace:980
+
+                    if (li && !li.previousSibling) {
+                        var parentList = li.parentNode;
+                        var bk = range.createBookmark();
+                        if(domUtils.isTagNode(parentList.parentNode,'ol ul')){
+                            parentList.parentNode.insertBefore(li,parentList);
+                            if(domUtils.isEmptyNode(parentList)){
+                                domUtils.remove(parentList)
+                            }
+                        }else{
+
+                            while(li.firstChild){
+                                parentList.parentNode.insertBefore(li.firstChild,parentList);
+                            }
+
+                            domUtils.remove(li);
+                            if(domUtils.isEmptyNode(parentList)){
+                                domUtils.remove(parentList)
+                            }
+
+                        }
+                        range.moveToBookmark(bk).setCursor(false,true);
+                        me.fireEvent('contentchange');
+                        me.fireEvent('saveScene');
+                        domUtils.preventDefault(evt);
+                        return;
+
+                    }
+
+
+                }
+
+
+            }
+
+        }
+    });
+
+    //处理tab键
+    me.addListener('tabkeydown',function(){
+        function listToArray(list){
+            var arr = [];
+            for(var p in list){
+                arr.push(p)
+            }
+            return arr;
+        }
+        var range = me.selection.getRange(),
+            listStyle = {
+                'OL':listToArray(me.options.insertorderedlist),
+                'UL':listToArray(me.options.insertunorderedlist)
+            };
+        //控制级数
+        function checkLevel(li){
+            if(me.options.maxListLevel != -1){
+                var level = li.parentNode,levelNum = 0;
+                while(/[ou]l/i.test(level.tagName)){
+                    levelNum++;
+                    level = level.parentNode;
+                }
+                if(levelNum >= me.options.maxListLevel){
+                    return true;
+                }
+            }
+        }
+        //只以开始为准
+        //todo 后续改进
+        var li = domUtils.findParentByTagName(range.startContainer, 'li', true);
+        if(li){
+
+            var bk;
+            if(range.collapsed){
+                if(checkLevel(li))
+                    return true;
+                var parentLi = li.parentNode,
+                    list = me.document.createElement(parentLi.tagName),
+                    index = utils.indexOf(listStyle[list.tagName], getStyle(parentLi)||domUtils.getComputedStyle(parentLi, 'list-style-type'));
+                index = index + 1 == listStyle[list.tagName].length ? 0 : index + 1;
+                var currentStyle = listStyle[list.tagName][index];
+                setListStyle(list,currentStyle);
+                if(domUtils.isStartInblock(range)){
+                    me.fireEvent('saveScene');
+                    bk = range.createBookmark();
+                    parentLi.insertBefore(list, li);
+                    list.appendChild(li);
+                    adjustList(list,list.tagName.toLowerCase(),currentStyle);
+                    me.fireEvent('contentchange');
+                    range.moveToBookmark(bk).select(true);
+                    return true;
+                }
+            }else{
+                me.fireEvent('saveScene');
+                bk = range.createBookmark();
+                for(var i= 0,closeList,parents = domUtils.findParents(li),ci;ci=parents[i++];){
+                    if(domUtils.isTagNode(ci,'ol ul')){
+                        closeList = ci;
+                        break;
+                    }
+                }
+                var current = li;
+                if(bk.end){
+                    while(current && !(domUtils.getPosition(current, bk.end) & domUtils.POSITION_FOLLOWING)){
+                        if(checkLevel(current)){
+                            current = domUtils.getNextDomNode(current,false,null,function(node){return node !== closeList});
+                            continue;
+                        }
+                        var parentLi = current.parentNode,
+                            list = me.document.createElement(parentLi.tagName),
+                            index = utils.indexOf(listStyle[list.tagName], getStyle(parentLi)||domUtils.getComputedStyle(parentLi, 'list-style-type'));
+                        var currentIndex = index + 1 == listStyle[list.tagName].length ? 0 : index + 1;
+                        var currentStyle = listStyle[list.tagName][currentIndex];
+                        setListStyle(list,currentStyle);
+                        parentLi.insertBefore(list, current);
+                        while(current && !(domUtils.getPosition(current, bk.end) & domUtils.POSITION_FOLLOWING)){
+                            li = current.nextSibling;
+                            list.appendChild(current);
+                            if(!li || domUtils.isTagNode(li,'ol ul')){
+                                if(li){
+                                    while(li = li.firstChild){
+                                        if(li.tagName == 'LI'){
+                                            break;
+                                        }
+                                    }
+                                }else{
+                                    li = domUtils.getNextDomNode(current,false,null,function(node){return node !== closeList});
+                                }
+                                break;
+                            }
+                            current = li;
+                        }
+                        adjustList(list,list.tagName.toLowerCase(),currentStyle);
+                        current = li;
+                    }
+                }
+                me.fireEvent('contentchange');
+                range.moveToBookmark(bk).select();
+                return true;
+            }
+        }
+
+    });
+
+    me.commands['insertorderedlist'] =
+    me.commands['insertunorderedlist'] = {
+            execCommand:function (command, style) {
+
+                if (!style) {
+                    style = command.toLowerCase() == 'insertorderedlist' ? 'decimal' : 'disc';
+                }
+                var me = this,
+                    range = this.selection.getRange(),
+                    filterFn = function (node) {
+                        return   node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' : !domUtils.isWhitespace(node);
+                    },
+                    tag = command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul',
+                    frag = me.document.createDocumentFragment();
+                //去掉是因为会出现选到末尾,导致adjustmentBoundary缩到ol/ul的位置
+                //range.shrinkBoundary();//.adjustmentBoundary();
+                range.adjustmentBoundary().shrinkBoundary();
+                var bko = range.createBookmark(true),
+                    start = domUtils.findParentByTagName(me.document.getElementById(bko.start), 'li'),
+                    modifyStart = 0,
+                    end = domUtils.findParentByTagName(me.document.getElementById(bko.end), 'li'),
+                    modifyEnd = 0,
+                    startParent, endParent,
+                    list, tmp;
+
+                if (start || end) {
+                    start && (startParent = start.parentNode);
+                    if (!bko.end) {
+                        end = start;
+                    }
+                    end && (endParent = end.parentNode);
+
+                    if (startParent === endParent) {
+                        while (start !== end) {
+                            tmp = start;
+                            start = start.nextSibling;
+                            if (!domUtils.isBlockElm(tmp.firstChild)) {
+                                var p = me.document.createElement('p');
+                                while (tmp.firstChild) {
+                                    p.appendChild(tmp.firstChild);
+                                }
+                                tmp.appendChild(p);
+                            }
+                            frag.appendChild(tmp);
+                        }
+                        tmp = me.document.createElement('span');
+                        startParent.insertBefore(tmp, end);
+                        if (!domUtils.isBlockElm(end.firstChild)) {
+                            p = me.document.createElement('p');
+                            while (end.firstChild) {
+                                p.appendChild(end.firstChild);
+                            }
+                            end.appendChild(p);
+                        }
+                        frag.appendChild(end);
+                        domUtils.breakParent(tmp, startParent);
+                        if (domUtils.isEmptyNode(tmp.previousSibling)) {
+                            domUtils.remove(tmp.previousSibling);
+                        }
+                        if (domUtils.isEmptyNode(tmp.nextSibling)) {
+                            domUtils.remove(tmp.nextSibling)
+                        }
+                        var nodeStyle = getStyle(startParent) || domUtils.getComputedStyle(startParent, 'list-style-type') || (command.toLowerCase() == 'insertorderedlist' ? 'decimal' : 'disc');
+                        if (startParent.tagName.toLowerCase() == tag && nodeStyle == style) {
+                            for (var i = 0, ci, tmpFrag = me.document.createDocumentFragment(); ci = frag.childNodes[i++];) {
+                                if(domUtils.isTagNode(ci,'ol ul')){
+                                    utils.each(domUtils.getElementsByTagName(ci,'li'),function(li){
+                                        while(li.firstChild){
+                                            tmpFrag.appendChild(li.firstChild);
+                                        }
+
+                                    });
+                                }else{
+                                    while (ci.firstChild) {
+                                        tmpFrag.appendChild(ci.firstChild);
+                                    }
+                                }
+
+                            }
+                            tmp.parentNode.insertBefore(tmpFrag, tmp);
+                        } else {
+                            list = me.document.createElement(tag);
+                            setListStyle(list,style);
+                            list.appendChild(frag);
+                            tmp.parentNode.insertBefore(list, tmp);
+                        }
+
+                        domUtils.remove(tmp);
+                        list && adjustList(list, tag, style);
+                        range.moveToBookmark(bko).select();
+                        return;
+                    }
+                    //开始
+                    if (start) {
+                        while (start) {
+                            tmp = start.nextSibling;
+                            if (domUtils.isTagNode(start, 'ol ul')) {
+                                frag.appendChild(start);
+                            } else {
+                                var tmpfrag = me.document.createDocumentFragment(),
+                                    hasBlock = 0;
+                                while (start.firstChild) {
+                                    if (domUtils.isBlockElm(start.firstChild)) {
+                                        hasBlock = 1;
+                                    }
+                                    tmpfrag.appendChild(start.firstChild);
+                                }
+                                if (!hasBlock) {
+                                    var tmpP = me.document.createElement('p');
+                                    tmpP.appendChild(tmpfrag);
+                                    frag.appendChild(tmpP);
+                                } else {
+                                    frag.appendChild(tmpfrag);
+                                }
+                                domUtils.remove(start);
+                            }
+
+                            start = tmp;
+                        }
+                        startParent.parentNode.insertBefore(frag, startParent.nextSibling);
+                        if (domUtils.isEmptyNode(startParent)) {
+                            range.setStartBefore(startParent);
+                            domUtils.remove(startParent);
+                        } else {
+                            range.setStartAfter(startParent);
+                        }
+                        modifyStart = 1;
+                    }
+
+                    if (end && domUtils.inDoc(endParent, me.document)) {
+                        //结束
+                        start = endParent.firstChild;
+                        while (start && start !== end) {
+                            tmp = start.nextSibling;
+                            if (domUtils.isTagNode(start, 'ol ul')) {
+                                frag.appendChild(start);
+                            } else {
+                                tmpfrag = me.document.createDocumentFragment();
+                                hasBlock = 0;
+                                while (start.firstChild) {
+                                    if (domUtils.isBlockElm(start.firstChild)) {
+                                        hasBlock = 1;
+                                    }
+                                    tmpfrag.appendChild(start.firstChild);
+                                }
+                                if (!hasBlock) {
+                                    tmpP = me.document.createElement('p');
+                                    tmpP.appendChild(tmpfrag);
+                                    frag.appendChild(tmpP);
+                                } else {
+                                    frag.appendChild(tmpfrag);
+                                }
+                                domUtils.remove(start);
+                            }
+                            start = tmp;
+                        }
+                        var tmpDiv = domUtils.createElement(me.document, 'div', {
+                            'tmpDiv':1
+                        });
+                        domUtils.moveChild(end, tmpDiv);
+
+                        frag.appendChild(tmpDiv);
+                        domUtils.remove(end);
+                        endParent.parentNode.insertBefore(frag, endParent);
+                        range.setEndBefore(endParent);
+                        if (domUtils.isEmptyNode(endParent)) {
+                            domUtils.remove(endParent);
+                        }
+
+                        modifyEnd = 1;
+                    }
+
+
+                }
+
+                if (!modifyStart) {
+                    range.setStartBefore(me.document.getElementById(bko.start));
+                }
+                if (bko.end && !modifyEnd) {
+                    range.setEndAfter(me.document.getElementById(bko.end));
+                }
+                range.enlarge(true, function (node) {
+                    return notExchange[node.tagName];
+                });
+
+                frag = me.document.createDocumentFragment();
+
+                var bk = range.createBookmark(),
+                    current = domUtils.getNextDomNode(bk.start, false, filterFn),
+                    tmpRange = range.cloneRange(),
+                    tmpNode,
+                    block = domUtils.isBlockElm;
+
+                while (current && current !== bk.end && (domUtils.getPosition(current, bk.end) & domUtils.POSITION_PRECEDING)) {
+
+                    if (current.nodeType == 3 || dtd.li[current.tagName]) {
+                        if (current.nodeType == 1 && dtd.$list[current.tagName]) {
+                            while (current.firstChild) {
+                                frag.appendChild(current.firstChild);
+                            }
+                            tmpNode = domUtils.getNextDomNode(current, false, filterFn);
+                            domUtils.remove(current);
+                            current = tmpNode;
+                            continue;
+
+                        }
+                        tmpNode = current;
+                        tmpRange.setStartBefore(current);
+
+                        while (current && current !== bk.end && (!block(current) || domUtils.isBookmarkNode(current) )) {
+                            tmpNode = current;
+                            current = domUtils.getNextDomNode(current, false, null, function (node) {
+                                return !notExchange[node.tagName];
+                            });
+                        }
+
+                        if (current && block(current)) {
+                            tmp = domUtils.getNextDomNode(tmpNode, false, filterFn);
+                            if (tmp && domUtils.isBookmarkNode(tmp)) {
+                                current = domUtils.getNextDomNode(tmp, false, filterFn);
+                                tmpNode = tmp;
+                            }
+                        }
+                        tmpRange.setEndAfter(tmpNode);
+
+                        current = domUtils.getNextDomNode(tmpNode, false, filterFn);
+
+                        var li = range.document.createElement('li');
+
+                        li.appendChild(tmpRange.extractContents());
+                        if(domUtils.isEmptyNode(li)){
+                            var tmpNode = range.document.createElement('p');
+                            while(li.firstChild){
+                                tmpNode.appendChild(li.firstChild)
+                            }
+                            li.appendChild(tmpNode);
+                        }
+                        frag.appendChild(li);
+                    } else {
+                        current = domUtils.getNextDomNode(current, true, filterFn);
+                    }
+                }
+                range.moveToBookmark(bk).collapse(true);
+                list = me.document.createElement(tag);
+                setListStyle(list,style);
+                list.appendChild(frag);
+                range.insertNode(list);
+                //当前list上下看能否合并
+                adjustList(list, tag, style,true);
+                //去掉冗余的tmpDiv
+                for (var i = 0, ci, tmpDivs = domUtils.getElementsByTagName(list, 'div'); ci = tmpDivs[i++];) {
+                    if (ci.getAttribute('tmpDiv')) {
+                        domUtils.remove(ci, true)
+                    }
+                }
+                range.moveToBookmark(bko).select();
+
+            },
+            queryCommandState:function (command) {
+                return domUtils.filterNodeList(this.selection.getStartElementPath(), command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul') ? 1 : 0;
+            },
+            queryCommandValue:function (command) {
+                var node = domUtils.filterNodeList(this.selection.getStartElementPath(), command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul');
+                return node ? getStyle(node) || domUtils.getComputedStyle(node, 'list-style-type') : null;
+            }
+        };
+};
+

+ 75 - 0
web/js/ueditor2/_src/plugins/music.js

@@ -0,0 +1,75 @@
+///import core
+///import plugins/inserthtml.js
+///commands 音乐
+///commandsName Music
+///commandsTitle  插入音乐
+///commandsDialog  dialogs\music
+UE.plugins['music'] = function () {
+    var me = this,
+        div;
+
+    /**
+     * 创建插入音乐字符窜
+     * @param url 音乐地址
+     * @param width 音乐宽度
+     * @param height 音乐高度
+     * @param align 阴雨对齐
+     * @param toEmbed 是否以flash代替显示
+     * @param addParagraph  是否需要添加P标签
+     */
+    function creatInsertStr(url,width,height,align,toEmbed,addParagraph){
+        return  !toEmbed ?
+            (addParagraph? ('<p '+ (align !="none" ? ( align == "center"? ' style="text-align:center;" ':' style="float:"'+ align ) : '') + '>'): '') +
+                '<img align="'+align+'" width="'+ width +'" height="' + height + '" _url="'+url+'" class="edui-faked-music"' +
+                ' src="'+me.options.langPath+me.options.lang+'/images/music.png" />' +
+                (addParagraph?'</p>':'')
+            :
+            '<embed type="application/x-shockwave-flash" class="edui-faked-music" pluginspage="http://www.macromedia.com/go/getflashplayer"' +
+                ' src="' + url + '" width="' + width  + '" height="' + height  + '" align="' + align + '"' +
+                ( align !="none" ? ' style= "'+ ( align == "center"? "display:block;":" float: "+ align )  + '"' :'' ) +
+                ' wmode="transparent" play="true" loop="false" menu="false" allowscriptaccess="never" allowfullscreen="true" >';
+    }
+
+    function switchImgAndEmbed(img2embed) {
+        var tmpdiv,
+            nodes = domUtils.getElementsByTagName(me.document, !img2embed ? "embed" : "img");
+        for (var i = 0, node; node = nodes[i++];) {
+            if (node.className != "edui-faked-music") {
+                continue;
+            }
+            tmpdiv = me.document.createElement("div");
+            //先看float在看align,浮动有的是时候是在float上定义的
+            var align = domUtils.getComputedStyle(node,'float');
+            align = align == 'none' ? (node.getAttribute('align') || '') : align;
+            tmpdiv.innerHTML = creatInsertStr(img2embed ? node.getAttribute("_url") : node.getAttribute("src"), node.width, node.height, align, img2embed);
+            node.parentNode.replaceChild(tmpdiv.firstChild, node);
+        }
+    }
+
+    me.addListener("beforegetcontent", function () {
+        switchImgAndEmbed(true);
+    });
+    me.addListener('aftersetcontent', function () {
+        switchImgAndEmbed(false);
+    });
+    me.addListener('aftergetcontent', function (cmdName) {
+        if (cmdName == 'aftergetcontent' && me.queryCommandState('source')) {
+            return;
+        }
+        switchImgAndEmbed(false);
+    });
+
+    me.commands["music"] = {
+        execCommand:function (cmd, musicObj) {
+            var me = this,
+                str = creatInsertStr(musicObj.url, musicObj.width || 400, musicObj.height || 95, "none", false, true);
+            me.execCommand("inserthtml",str);
+        },
+        queryCommandState:function () {
+            var me = this,
+                img = me.selection.getRange().getClosedNode(),
+                flag = img && (img.className == "edui-faked-music");
+            return flag ? 1 : 0;
+        }
+    };
+};

+ 128 - 0
web/js/ueditor2/_src/plugins/pagebreak.js

@@ -0,0 +1,128 @@
+///import core
+///commands 添加分页功能
+///commandsName  PageBreak
+///commandsTitle  分页
+/**
+ * @description 添加分页功能
+ * @author zhanyi
+ */
+UE.plugins['pagebreak'] = function () {
+    var me = this,
+        notBreakTags = ['td'];
+
+    function fillNode(node){
+        if(domUtils.isEmptyBlock(node)){
+            var firstChild = node.firstChild,tmpNode;
+
+            while(firstChild && firstChild.nodeType == 1 && domUtils.isEmptyBlock(firstChild)){
+                tmpNode = firstChild;
+                firstChild = firstChild.firstChild;
+            }
+            !tmpNode && (tmpNode = node);
+            domUtils.fillNode(me.document,tmpNode);
+        }
+    }
+    //分页符样式添加
+
+    me.ready(function(){
+        utils.cssRule('pagebreak','.pagebreak{display:block;clear:both !important;cursor:default !important;width: 100% !important;margin:0;}',me.document);
+    });
+    function isHr(node){
+        return node && node.nodeType == 1 && node.tagName == 'HR' && node.className == 'pagebreak';
+    }
+    me.commands['pagebreak'] = {
+        execCommand:function () {
+            var range = me.selection.getRange(),hr = me.document.createElement('hr');
+            domUtils.setAttributes(hr,{
+                'class' : 'pagebreak',
+                noshade:"noshade",
+                size:"5"
+            });
+            domUtils.unSelectable(hr);
+            //table单独处理
+            var node = domUtils.findParentByTagName(range.startContainer, notBreakTags, true),
+
+                parents = [], pN;
+            if (node) {
+                switch (node.tagName) {
+                    case 'TD':
+                        pN = node.parentNode;
+                        if (!pN.previousSibling) {
+                            var table = domUtils.findParentByTagName(pN, 'table');
+//                            var tableWrapDiv = table.parentNode;
+//                            if(tableWrapDiv && tableWrapDiv.nodeType == 1
+//                                && tableWrapDiv.tagName == 'DIV'
+//                                && tableWrapDiv.getAttribute('dropdrag')
+//                                ){
+//                                domUtils.remove(tableWrapDiv,true);
+//                            }
+                            table.parentNode.insertBefore(hr, table);
+                            parents = domUtils.findParents(hr, true);
+
+                        } else {
+                            pN.parentNode.insertBefore(hr, pN);
+                            parents = domUtils.findParents(hr);
+
+                        }
+                        pN = parents[1];
+                        if (hr !== pN) {
+                            domUtils.breakParent(hr, pN);
+
+                        }
+                        //table要重写绑定一下拖拽
+                        me.fireEvent('afteradjusttable',me.document);
+                }
+
+            } else {
+
+                if (!range.collapsed) {
+                    range.deleteContents();
+                    var start = range.startContainer;
+                    while ( !domUtils.isBody(start) && domUtils.isBlockElm(start) && domUtils.isEmptyNode(start)) {
+                        range.setStartBefore(start).collapse(true);
+                        domUtils.remove(start);
+                        start = range.startContainer;
+                    }
+
+                }
+                range.insertNode(hr);
+
+                var pN = hr.parentNode, nextNode;
+                while (!domUtils.isBody(pN)) {
+                    domUtils.breakParent(hr, pN);
+                    nextNode = hr.nextSibling;
+                    if (nextNode && domUtils.isEmptyBlock(nextNode)) {
+                        domUtils.remove(nextNode);
+                    }
+                    pN = hr.parentNode;
+                }
+                nextNode = hr.nextSibling;
+                var pre = hr.previousSibling;
+                if(isHr(pre)){
+                    domUtils.remove(pre);
+                }else{
+                    pre && fillNode(pre);
+                }
+
+                if(!nextNode){
+                    var p = me.document.createElement('p');
+
+                    hr.parentNode.appendChild(p);
+                    domUtils.fillNode(me.document,p);
+                    range.setStart(p,0).collapse(true);
+                }else{
+                    if(isHr(nextNode)){
+                        domUtils.remove(nextNode);
+                    }else{
+                        fillNode(nextNode);
+                    }
+                    range.setEndAfter(hr).collapse(false);
+                }
+
+                range.select(true);
+
+            }
+
+        }
+    };
+};

+ 150 - 0
web/js/ueditor2/_src/plugins/paragraph.js

@@ -0,0 +1,150 @@
+///import core
+///commands 格式
+///commandsName  Paragraph
+///commandsTitle  段落格式
+/**
+ * 段落样式
+ * @function
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     paragraph插入段落执行命令
+ * @param   {String}   style               标签值为:'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
+ * @param   {String}   attrs               标签的属性
+ * @author zhanyi
+ */
+UE.plugins['paragraph'] = function() {
+    var me = this,
+        block = domUtils.isBlockElm,
+        notExchange = ['TD','LI','PRE'],
+
+        doParagraph = function(range,style,attrs,sourceCmdName){
+            var bookmark = range.createBookmark(),
+                filterFn = function( node ) {
+                    return   node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' &&  !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace( node );
+                },
+                para;
+
+            range.enlarge( true );
+            var bookmark2 = range.createBookmark(),
+                current = domUtils.getNextDomNode( bookmark2.start, false, filterFn ),
+                tmpRange = range.cloneRange(),
+                tmpNode;
+            while ( current && !(domUtils.getPosition( current, bookmark2.end ) & domUtils.POSITION_FOLLOWING) ) {
+                if ( current.nodeType == 3 || !block( current ) ) {
+                    tmpRange.setStartBefore( current );
+                    while ( current && current !== bookmark2.end && !block( current ) ) {
+                        tmpNode = current;
+                        current = domUtils.getNextDomNode( current, false, null, function( node ) {
+                            return !block( node );
+                        } );
+                    }
+                    tmpRange.setEndAfter( tmpNode );
+                    
+                    para = range.document.createElement( style );
+                    if(attrs){
+                        domUtils.setAttributes(para,attrs);
+                        if(sourceCmdName && sourceCmdName == 'customstyle' && attrs.style){
+                            para.style.cssText = attrs.style;
+                        }
+                    }
+                    para.appendChild( tmpRange.extractContents() );
+                    //需要内容占位
+                    if(domUtils.isEmptyNode(para)){
+                        domUtils.fillChar(range.document,para);
+                        
+                    }
+
+                    tmpRange.insertNode( para );
+
+                    var parent = para.parentNode;
+                    //如果para上一级是一个block元素且不是body,td就删除它
+                    if ( block( parent ) && !domUtils.isBody( para.parentNode ) && utils.indexOf(notExchange,parent.tagName)==-1) {
+                        //存储dir,style
+                        if(!(sourceCmdName && sourceCmdName == 'customstyle')){
+                            parent.getAttribute('dir') && para.setAttribute('dir',parent.getAttribute('dir'));
+                            //trace:1070
+                            parent.style.cssText && (para.style.cssText = parent.style.cssText + ';' + para.style.cssText);
+                            //trace:1030
+                            parent.style.textAlign && !para.style.textAlign && (para.style.textAlign = parent.style.textAlign);
+                            parent.style.textIndent && !para.style.textIndent && (para.style.textIndent = parent.style.textIndent);
+                            parent.style.padding && !para.style.padding && (para.style.padding = parent.style.padding);
+                        }
+
+                        //trace:1706 选择的就是h1-6要删除
+                        if(attrs && /h\d/i.test(parent.tagName) && !/h\d/i.test(para.tagName) ){
+                            domUtils.setAttributes(parent,attrs);
+                            if(sourceCmdName && sourceCmdName == 'customstyle' && attrs.style){
+                                parent.style.cssText = attrs.style;
+                            }
+                            domUtils.remove(para,true);
+                            para = parent;
+                        }else{
+                            domUtils.remove( para.parentNode, true );
+                        }
+
+                    }
+                    if(  utils.indexOf(notExchange,parent.tagName)!=-1){
+                        current = parent;
+                    }else{
+                       current = para;
+                    }
+
+
+                    current = domUtils.getNextDomNode( current, false, filterFn );
+                } else {
+                    current = domUtils.getNextDomNode( current, true, filterFn );
+                }
+            }
+            return range.moveToBookmark( bookmark2 ).moveToBookmark( bookmark );
+        };
+    me.setOpt('paragraph',{'p':'', 'h1':'', 'h2':'', 'h3':'', 'h4':'', 'h5':'', 'h6':''});
+    me.commands['paragraph'] = {
+        execCommand : function( cmdName, style,attrs,sourceCmdName ) {
+            var range = this.selection.getRange();
+             //闭合时单独处理
+            if(range.collapsed){
+                var txt = this.document.createTextNode('p');
+                range.insertNode(txt);
+                //去掉冗余的fillchar
+                if(browser.ie){
+                    var node = txt.previousSibling;
+                    if(node && domUtils.isWhitespace(node)){
+                        domUtils.remove(node);
+                    }
+                    node = txt.nextSibling;
+                    if(node && domUtils.isWhitespace(node)){
+                        domUtils.remove(node);
+                    }
+                }
+
+            }
+            range = doParagraph(range,style,attrs,sourceCmdName);
+            if(txt){
+                range.setStartBefore(txt).collapse(true);
+                pN = txt.parentNode;
+
+                domUtils.remove(txt);
+
+                if(domUtils.isBlockElm(pN)&&domUtils.isEmptyNode(pN)){
+                    domUtils.fillNode(this.document,pN);
+                }
+
+            }
+
+            if(browser.gecko && range.collapsed && range.startContainer.nodeType == 1){
+                var child = range.startContainer.childNodes[range.startOffset];
+                if(child && child.nodeType == 1 && child.tagName.toLowerCase() == style){
+                    range.setStart(child,0).collapse(true);
+                }
+            }
+            //trace:1097 原来有true,原因忘了,但去了就不能清除多余的占位符了
+            range.select();
+
+
+            return true;
+        },
+        queryCommandValue : function() {
+            var node = domUtils.filterNodeList(this.selection.getStartElementPath(),'p h1 h2 h3 h4 h5 h6');
+            return node ? node.tagName.toLowerCase() : '';
+        }
+    };
+};

+ 311 - 0
web/js/ueditor2/_src/plugins/paste.js

@@ -0,0 +1,311 @@
+///import core
+///import plugins/inserthtml.js
+///import plugins/undo.js
+///import plugins/serialize.js
+///commands 粘贴
+///commandsName  PastePlain
+///commandsTitle  纯文本粘贴模式
+/*
+ ** @description 粘贴
+ * @author zhanyi
+ */
+(function() {
+    function getClipboardData( callback ) {
+
+        var doc = this.document;
+
+        if ( doc.getElementById( 'baidu_pastebin' ) ) {
+            return;
+        }
+
+        var range = this.selection.getRange(),
+            bk = range.createBookmark(),
+        //创建剪贴的容器div
+            pastebin = doc.createElement( 'div' );
+
+        pastebin.id = 'baidu_pastebin';
+
+
+        // Safari 要求div必须有内容,才能粘贴内容进来
+        browser.webkit && pastebin.appendChild( doc.createTextNode( domUtils.fillChar + domUtils.fillChar ) );
+        doc.body.appendChild( pastebin );
+        //trace:717 隐藏的span不能得到top
+        //bk.start.innerHTML = '&nbsp;';
+        bk.start.style.display = '';
+        pastebin.style.cssText = "position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:" +
+            //要在现在光标平行的位置加入,否则会出现跳动的问题
+            domUtils.getXY( bk.start ).y + 'px';
+
+        range.selectNodeContents( pastebin ).select( true );
+
+        setTimeout( function() {
+
+            if (browser.webkit) {
+
+                for(var i=0,pastebins = doc.querySelectorAll('#baidu_pastebin'),pi;pi=pastebins[i++];){
+                    if(domUtils.isEmptyNode(pi)){
+                        domUtils.remove(pi);
+                    }else{
+                        pastebin = pi;
+                        break;
+                    }
+                }
+
+
+            }
+
+            try{
+                pastebin.parentNode.removeChild(pastebin);
+            }catch(e){}
+
+            range.moveToBookmark( bk ).select(true);
+            callback( pastebin );
+        }, 0 );
+
+
+    }
+
+    UE.plugins['paste'] = function() {
+        var me = this;
+        var word_img_flag = {flag:""};
+
+        var pasteplain = me.options.pasteplain === true;
+        var modify_num = {flag:""};
+        me.commands['pasteplain'] = {
+            queryCommandState: function (){
+                return pasteplain;
+            },
+            execCommand: function (){
+                pasteplain = !pasteplain|0;
+            },
+            notNeedUndo : 1
+        };
+        var txtContent,htmlContent,address;
+
+        function filter(div){
+
+            var html;
+            if ( div.firstChild ) {
+                //去掉cut中添加的边界值
+                var nodes = domUtils.getElementsByTagName(div,'span');
+                  for(var i=0,ni;ni=nodes[i++];){
+                    if(ni.id == '_baidu_cut_start' || ni.id == '_baidu_cut_end'){
+                        domUtils.remove(ni);
+                    }
+                }
+
+                if(browser.webkit){
+
+                    var brs = div.querySelectorAll('div br');
+                    for(var i=0,bi;bi=brs[i++];){
+                        var pN = bi.parentNode;
+                        if(pN.tagName == 'DIV' && pN.childNodes.length ==1){
+                            pN.innerHTML = '<p><br/></p>';
+
+                            domUtils.remove(pN);
+                        }
+                    }
+                    var divs = div.querySelectorAll('#baidu_pastebin');
+                    for(var i=0,di;di=divs[i++];){
+                        var tmpP = me.document.createElement('p');
+                        di.parentNode.insertBefore(tmpP,di);
+                        while(di.firstChild){
+                            tmpP.appendChild(di.firstChild);
+                        }
+                        domUtils.remove(di);
+                    }
+
+                    var metas = div.querySelectorAll('meta');
+                    for(var i=0,ci;ci=metas[i++];){
+                        domUtils.remove(ci);
+                    }
+
+                    var brs = div.querySelectorAll('br');
+                    for(i=0;ci=brs[i++];){
+                        if(/^apple-/.test(ci)){
+                            domUtils.remove(ci);
+                        }
+                    }
+
+                    utils.each(domUtils.getElementsByTagName(div,'span',function(node){
+                        if(node.style.cssText){
+                            node.style.cssText =  node.style.cssText.replace(/white-space[^;]+;/g,'');
+                            if(!node.style.cssText){
+                                domUtils.removeAttributes(node,'style');
+                                if(domUtils.hasNoAttributes(node)){
+                                    return 1
+                                }
+                            }
+                        }
+                        return 0
+                    }),function(si){
+                        domUtils.remove(si,true)
+                    })
+                }
+                if(browser.gecko){
+                    var dirtyNodes = div.querySelectorAll('[_moz_dirty]');
+                    for(i=0;ci=dirtyNodes[i++];){
+                        ci.removeAttribute( '_moz_dirty' );
+                    }
+                }
+                if(!browser.ie ){
+                    var spans = div.querySelectorAll('span.Apple-style-span');
+                    for(var i=0,ci;ci=spans[i++];){
+                        domUtils.remove(ci,true);
+                    }
+                }
+
+                //ie下使用innerHTML会产生多余的\r\n字符,也会产生&nbsp;这里过滤掉
+                html = div.innerHTML.replace(/>(?:(\s|&nbsp;)*?)</g,'><');
+
+                var f = me.serialize;
+                if(f){
+                    //如果过滤出现问题,捕获它,直接插入内容,避免出现错误导致粘贴整个失败
+                    try{
+                        html = UE.filterWord(html);
+
+                        var node =  f.transformInput(
+                            f.parseHTML(
+                                //todo: 暂时不走dtd的过滤
+                                html//, true
+                            ),word_img_flag
+                        );
+                        //trace:924
+                        //纯文本模式也要保留段落
+                        node = f.filter(node,pasteplain ? {
+                            whiteList: {
+                                'p': {'br':1,'BR':1,$:{}},
+                                'br':{'$':{}},
+                                'div':{'br':1,'BR':1,'$':{}},
+                                'li':{'$':{}},
+                                'tr':{'td':1,'$':{}},
+                                'td':{'$':{}}
+
+                            },
+                            blackList: {
+                                'style':1,
+                                'script':1,
+                                'object':1
+                            }
+                        } : null, !pasteplain ? modify_num : null);
+
+                        if(browser.webkit){
+                            var length = node.children.length,
+                                child;
+                            while((child = node.children[length-1]) && child.tag == 'br'){
+                                node.children.splice(length-1,1);
+                                length = node.children.length;
+                            }
+                        }
+
+                        html = f.toHTML(node,pasteplain);
+
+                        txtContent = f.filter(node,{
+                            whiteList: {
+                                'p': {'br':1,'BR':1,$:{}},
+                                'br':{'$':{}},
+                                'div':{'br':1,'BR':1,'$':{},'table':1,'ul':1,'ol':1},
+                                'li':{'$':{}},
+                                'ul':{'li':1,'$':{}},
+                                'ol':{'li':1,'$':{}},
+                                'tr':{'td':1,'$':{}},
+                                'td':{'$':{}},
+                                'table': {'tr':1,'tbody':1,'td':1,'$':{}},
+                                'tbody': {'tr':1,'td':1,'$':{}},
+                                h1:{'$':{}},h2:{'$':{}},h3:{'$':{}},h4:{'$':{}},h5:{'$':{}},h6:{'$':{}}
+                            },
+                            blackList: {
+                                'style':1,
+                                'script':1,
+                                'object':1
+                            }
+                        });
+
+                        txtContent = f.toHTML(txtContent,true)
+
+                    }catch(e){}
+
+                }
+
+                //自定义的处理
+                html = {'html':html,'txtContent':txtContent};
+
+                me.fireEvent('beforepaste',html);
+                //不用在走过滤了
+                if(html.html){
+                    htmlContent = html.html;
+                    address = me.selection.getRange().createAddress(true);
+                    me.execCommand( 'insertHtml',htmlContent,true);
+                    me.fireEvent("afterpaste");
+                }
+
+            }
+        }
+
+        me.addListener('pasteTransfer',function(cmd,plainType){
+            if(address && txtContent && htmlContent && txtContent != htmlContent){
+                var range = me.selection.getRange();
+                range.moveToAddress(address,true).deleteContents();
+                range.select(true);
+                me.__hasEnterExecCommand = true;
+                var html = htmlContent;
+                if(plainType === 2){
+                    html = html.replace(/<(\/?)([\w\-]+)([^>]*)>/gi,function(a,b,tagName,attrs){
+                        tagName = tagName.toLowerCase();
+                        if({img:1}[tagName]){
+                            return a;
+                        }
+                        attrs = attrs.replace(/([\w\-]*?)\s*=\s*(("([^"]*)")|('([^']*)')|([^\s>]+))/gi,function(str,atr,val){
+                            if({
+                                'src':1,
+                                'href':1,
+                                'name':1
+                            }[atr.toLowerCase()]){
+                                return atr + '=' + val + ' '
+                            }
+                            return ''
+                        });
+                        if({
+                            'span':1,
+                            'div':1
+                        }[tagName]){
+                            return ''
+                        }else{
+
+                            return '<' + b + tagName + ' ' + utils.trim(attrs) + '>'
+                        }
+
+                    });
+                }else if(plainType){
+                    html = txtContent;
+                }
+                me.execCommand('inserthtml',html,true);
+                me.__hasEnterExecCommand = false;
+                var tmpAddress = me.selection.getRange().createAddress(true);
+                address.endAddress = tmpAddress.startAddress;
+            }
+        });
+        me.addListener('ready',function(){
+            domUtils.on(me.body,'cut',function(){
+                var range = me.selection.getRange();
+                if(!range.collapsed && me.undoManger){
+                    me.undoManger.save();
+                }
+
+            });
+            //ie下beforepaste在点击右键时也会触发,所以用监控键盘才处理
+            domUtils.on(me.body, browser.ie || browser.opera ? 'keydown' : 'paste',function(e){
+                if((browser.ie || browser.opera) && ((!e.ctrlKey && !e.metaKey) || e.keyCode != '86')){
+                    return;
+                }
+                getClipboardData.call( me, function( div ) {
+                    filter(div);
+                } );
+            });
+
+        });
+
+    };
+
+})();
+

+ 25 - 0
web/js/ueditor2/_src/plugins/preview.js

@@ -0,0 +1,25 @@
+///import core
+///commands 预览
+///commandsName  Preview
+///commandsTitle  预览
+/**
+ * 预览
+ * @function
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     preview预览编辑器内容
+ */
+UE.commands['preview'] = {
+    execCommand : function(){
+        var w = window.open('', '_blank', ''),
+            d = w.document;
+        d.open();
+        d.write('<html><head><script src="'+this.options.UEDITOR_HOME_URL+'uparse.js"></script><script>' +
+            "setTimeout(function(){uParse('div',{" +
+            "    'highlightJsUrl':'"+this.options.UEDITOR_HOME_URL+"third-party/SyntaxHighlighter/shCore.js'," +
+                "    'highlightCssUrl':'"+this.options.UEDITOR_HOME_URL+"third-party/SyntaxHighlighter/shCoreDefault.css'" +
+                "})},300)" +
+            '</script></head><body><div>'+this.getContent(null,null,true)+'</div></body></html>');
+        d.close();
+    },
+    notNeedUndo : 1
+};

+ 17 - 0
web/js/ueditor2/_src/plugins/print.js

@@ -0,0 +1,17 @@
+///import core
+///commands 打印
+///commandsName  Print
+///commandsTitle  打印
+/**
+ * @description 打印
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     print打印编辑器内容
+ * @author zhanyi
+ */
+UE.commands['print'] = {
+    execCommand : function(){
+        this.window.print();
+    },
+    notNeedUndo : 1
+};
+

+ 176 - 0
web/js/ueditor2/_src/plugins/removeformat.js

@@ -0,0 +1,176 @@
+///import core
+///commands 清除格式
+///commandsName  RemoveFormat
+///commandsTitle  清除格式
+/**
+ * @description 清除格式
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     removeformat清除格式命令
+ * @param   {String}   tags                以逗号隔开的标签。如:span,a
+ * @param   {String}   style               样式
+ * @param   {String}   attrs               属性
+ * @param   {String}   notIncluedA    是否把a标签切开
+ * @author zhanyi
+ */
+UE.plugins['removeformat'] = function(){
+    var me = this;
+    me.setOpt({
+       'removeFormatTags': 'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var',
+       'removeFormatAttributes':'class,style,lang,width,height,align,hspace,valign'
+    });
+    me.commands['removeformat'] = {
+        execCommand : function( cmdName, tags, style, attrs,notIncludeA ) {
+
+            var tagReg = new RegExp( '^(?:' + (tags || this.options.removeFormatTags).replace( /,/g, '|' ) + ')$', 'i' ) ,
+                removeFormatAttributes = style ? [] : (attrs || this.options.removeFormatAttributes).split( ',' ),
+                range = new dom.Range( this.document ),
+                bookmark,node,parent,
+                filter = function( node ) {
+                    return node.nodeType == 1;
+                };
+
+            function isRedundantSpan (node) {
+                if (node.nodeType == 3 || node.tagName.toLowerCase() != 'span'){
+                    return 0;
+                }
+                if (browser.ie) {
+                    //ie 下判断实效,所以只能简单用style来判断
+                    //return node.style.cssText == '' ? 1 : 0;
+                    var attrs = node.attributes;
+                    if ( attrs.length ) {
+                        for ( var i = 0,l = attrs.length; i<l; i++ ) {
+                            if ( attrs[i].specified ) {
+                                return 0;
+                            }
+                        }
+                        return 1;
+                    }
+                }
+                return !node.attributes.length;
+            }
+            function doRemove( range ) {
+
+                var bookmark1 = range.createBookmark();
+                if ( range.collapsed ) {
+                    range.enlarge( true );
+                }
+
+                //不能把a标签切了
+                if(!notIncludeA){
+                    var aNode = domUtils.findParentByTagName(range.startContainer,'a',true);
+                    if(aNode){
+                        range.setStartBefore(aNode);
+                    }
+
+                    aNode = domUtils.findParentByTagName(range.endContainer,'a',true);
+                    if(aNode){
+                        range.setEndAfter(aNode);
+                    }
+
+                }
+
+
+                bookmark = range.createBookmark();
+
+                node = bookmark.start;
+
+                //切开始
+                while ( (parent = node.parentNode) && !domUtils.isBlockElm( parent ) ) {
+                    domUtils.breakParent( node, parent );
+
+                    domUtils.clearEmptySibling( node );
+                }
+                if ( bookmark.end ) {
+                    //切结束
+                    node = bookmark.end;
+                    while ( (parent = node.parentNode) && !domUtils.isBlockElm( parent ) ) {
+                        domUtils.breakParent( node, parent );
+                        domUtils.clearEmptySibling( node );
+                    }
+
+                    //开始去除样式
+                    var current = domUtils.getNextDomNode( bookmark.start, false, filter ),
+                        next;
+                    while ( current ) {
+                        if ( current == bookmark.end ) {
+                            break;
+                        }
+
+                        next = domUtils.getNextDomNode( current, true, filter );
+
+                        if ( !dtd.$empty[current.tagName.toLowerCase()] && !domUtils.isBookmarkNode( current ) ) {
+                            if ( tagReg.test( current.tagName ) ) {
+                                if ( style ) {
+                                    domUtils.removeStyle( current, style );
+                                    if ( isRedundantSpan( current ) && style != 'text-decoration'){
+                                        domUtils.remove( current, true );
+                                    }
+                                } else {
+                                    domUtils.remove( current, true );
+                                }
+                            } else {
+                                //trace:939  不能把list上的样式去掉
+                                if(!dtd.$tableContent[current.tagName] && !dtd.$list[current.tagName]){
+                                    domUtils.removeAttributes( current, removeFormatAttributes );
+                                    if ( isRedundantSpan( current ) ){
+                                        domUtils.remove( current, true );
+                                    }
+                                }
+
+                            }
+                        }
+                        current = next;
+                    }
+                }
+                //trace:1035
+                //trace:1096 不能把td上的样式去掉,比如边框
+                var pN = bookmark.start.parentNode;
+                if(domUtils.isBlockElm(pN) && !dtd.$tableContent[pN.tagName] && !dtd.$list[pN.tagName]){
+                    domUtils.removeAttributes(  pN,removeFormatAttributes );
+                }
+                pN = bookmark.end.parentNode;
+                if(bookmark.end && domUtils.isBlockElm(pN) && !dtd.$tableContent[pN.tagName]&& !dtd.$list[pN.tagName]){
+                    domUtils.removeAttributes(  pN,removeFormatAttributes );
+                }
+                range.moveToBookmark( bookmark ).moveToBookmark(bookmark1);
+                //清除冗余的代码 <b><bookmark></b>
+                var node = range.startContainer,
+                    tmp,
+                    collapsed = range.collapsed;
+                while(node.nodeType == 1 && domUtils.isEmptyNode(node) && dtd.$removeEmpty[node.tagName]){
+                    tmp = node.parentNode;
+                    range.setStartBefore(node);
+                    //trace:937
+                    //更新结束边界
+                    if(range.startContainer === range.endContainer){
+                        range.endOffset--;
+                    }
+                    domUtils.remove(node);
+                    node = tmp;
+                }
+
+                if(!collapsed){
+                    node = range.endContainer;
+                    while(node.nodeType == 1 && domUtils.isEmptyNode(node) && dtd.$removeEmpty[node.tagName]){
+                        tmp = node.parentNode;
+                        range.setEndBefore(node);
+                        domUtils.remove(node);
+
+                        node = tmp;
+                    }
+
+
+                }
+            }
+
+
+
+            range = this.selection.getRange();
+            doRemove( range );
+            range.select();
+
+        }
+
+    };
+
+};

+ 40 - 0
web/js/ueditor2/_src/plugins/rowspacing.js

@@ -0,0 +1,40 @@
+///import core
+///import plugins\paragraph.js
+///commands 段间距
+///commandsName  RowSpacingBottom,RowSpacingTop
+///commandsTitle  段间距
+/**
+ * @description 设置段前距,段后距
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName     rowspacing设置段间距
+ * @param   {String}   value              值,以px为单位
+ * @param   {String}   dir          top或bottom段前后段后
+ * @author zhanyi
+ */
+UE.plugins['rowspacing'] = function(){
+    var me = this;
+    me.setOpt({
+        'rowspacingtop':['5', '10', '15', '20', '25'],
+        'rowspacingbottom':['5', '10', '15', '20', '25']
+
+    });
+    me.commands['rowspacing'] =  {
+        execCommand : function( cmdName,value,dir ) {
+            this.execCommand('paragraph','p',{style:'margin-'+dir+':'+value + 'px'});
+            return true;
+        },
+        queryCommandValue : function(cmdName,dir) {
+            var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),function(node){return domUtils.isBlockElm(node) }),
+                value;
+            //trace:1026
+            if(pN){
+                value = domUtils.getComputedStyle(pN,'margin-'+dir).replace(/[^\d]/g,'');
+                return !value ? 0 : value;
+            }
+            return 0;
+
+        }
+    };
+};
+
+

+ 10 - 0
web/js/ueditor2/_src/plugins/scrawl.js

@@ -0,0 +1,10 @@
+///import core
+///commands 涂鸦
+///commandsName  Scrawl
+///commandsTitle  涂鸦
+///commandsDialog  dialogs\scrawl
+UE.commands['scrawl'] = {
+    queryCommandState : function(){
+        return ( browser.ie && browser.version  <= 8 ) ? -1 :0;
+    }
+};

+ 144 - 0
web/js/ueditor2/_src/plugins/searchreplace.js

@@ -0,0 +1,144 @@
+///import core
+///commands 查找替换
+///commandsName  SearchReplace
+///commandsTitle  查询替换
+///commandsDialog  dialogs\searchreplace
+/**
+ * @description 查找替换
+ * @author zhanyi
+ */
+UE.plugins['searchreplace'] = function(){
+
+    var currentRange,
+        first,
+        me = this;
+    me.addListener('reset',function(){
+        currentRange = null;
+        first = null;
+    });
+    me.commands['searchreplace'] = {
+        execCommand : function(cmdName,opt){
+            var me = this,
+                sel = me.selection,
+                range,
+                nativeRange,
+                num = 0,
+                opt = utils.extend(opt,{
+                    all : false,
+                    casesensitive : false,
+                    dir : 1
+                },true);
+
+            if(browser.ie){
+                while(1){
+                    var tmpRange;
+                    nativeRange = me.document.selection.createRange();
+                    tmpRange = nativeRange.duplicate();
+                    tmpRange.moveToElementText(me.document.body);
+                    if(opt.all){
+                        first = 0;
+                        opt.dir = 1;
+                        if(currentRange){
+                            tmpRange.setEndPoint(opt.dir == -1 ? 'EndToStart' : 'StartToEnd',currentRange);
+                        }
+                        tmpRange.moveToElementText(me.document.body);
+                    }else{
+                        tmpRange.setEndPoint(opt.dir == -1 ? 'EndToStart' : 'StartToEnd',nativeRange);
+                        if(opt.hasOwnProperty("replaceStr")){
+                            tmpRange.setEndPoint(opt.dir == -1 ? 'StartToEnd' : 'EndToStart',nativeRange);
+                        }
+                    }
+                    nativeRange = tmpRange.duplicate();
+
+
+
+                    if(!tmpRange.findText(opt.searchStr,opt.dir,opt.casesensitive ? 4 : 0)){
+                        currentRange = null;
+                        tmpRange = me.document.selection.createRange();
+                        tmpRange.scrollIntoView();
+                        return num;
+                    }
+                    tmpRange.select();
+                    //替换
+                    if(opt.hasOwnProperty("replaceStr")){
+                        range = sel.getRange();
+                        range.deleteContents().insertNode(range.document.createTextNode(opt.replaceStr)).select();
+                        currentRange = sel.getNative().createRange();
+
+                    }
+                    num++;
+                    if(!opt.all){
+                        break;
+                    }
+                }
+            }else{
+                var w = me.window,nativeSel = sel.getNative(),tmpRange;
+                while(1){
+                    if(opt.all){
+                        if(currentRange){
+                            currentRange.collapse(false);
+                            nativeRange = currentRange;
+                        }else{
+                            nativeRange  = me.document.createRange();
+                        }
+                        nativeRange.setStart(me.document.body,0);
+                        nativeRange.collapse(true);
+                        nativeSel.removeAllRanges();
+                        nativeSel.addRange( nativeRange );
+                        first = 0;
+                        opt.dir = 1;
+                    }else{
+                        //safari弹出层,原生已经找不到range了,所以需要先选回来,再取原生
+                        if(browser.safari){
+                            me.selection.getRange().select();
+
+                        }
+                        nativeRange = w.getSelection().getRangeAt(0);
+
+
+
+                        if(opt.hasOwnProperty("replaceStr")){
+                            nativeRange.collapse(opt.dir == 1 ? true : false);
+                        }
+                    }
+
+                    //如果是第一次并且海选中了内容那就要清除,为find做准备
+
+                    if(!first){
+                        nativeRange.collapse( opt.dir <0 ? true : false);
+                        nativeSel.removeAllRanges();
+                        nativeSel.addRange( nativeRange );
+                    }else{
+                        nativeSel.removeAllRanges();
+                    }
+
+                    if(!w.find(opt.searchStr,opt.casesensitive,opt.dir < 0 ? true : false) ) {
+                        currentRange = null;
+                        nativeSel.removeAllRanges();
+                        return num;
+                    }
+                    first = 0;
+                    range = w.getSelection().getRangeAt(0);
+                    if(!range.collapsed){
+
+                        if(opt.hasOwnProperty("replaceStr")){
+                            range.deleteContents();
+                            var text = w.document.createTextNode(opt.replaceStr);
+                            range.insertNode(text);
+                            range.selectNode(text);
+                            nativeSel.addRange(range);
+                            currentRange = range.cloneRange();
+                        }
+                    }
+                    num++;
+                    if(!opt.all){
+                        break;
+                    }
+                }
+
+            }
+            return true;
+        }
+    };
+
+};

+ 75 - 0
web/js/ueditor2/_src/plugins/selectall.js

@@ -0,0 +1,75 @@
+///import core
+///commands 全选
+///commandsName  SelectAll
+///commandsTitle  全选
+/**
+ * 选中所有
+ * @function
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName    selectall选中编辑器里的所有内容
+ * @author zhanyi
+*/
+UE.plugins['selectall'] = function(){
+    var me = this;
+    me.commands['selectall'] = {
+        execCommand : function(){
+            //去掉了原生的selectAll,因为会出现报错和当内容为空时,不能出现闭合状态的光标
+            var me = this,body = me.body,
+                range = me.selection.getRange();
+            range.selectNodeContents(body);
+            if(domUtils.isEmptyBlock(body)){
+                //opera不能自动合并到元素的里边,要手动处理一下
+                if(browser.opera && body.firstChild && body.firstChild.nodeType == 1){
+                    range.setStartAtFirst(body.firstChild);
+                }
+                range.collapse(true);
+            }
+            range.select(true);
+        },
+        notNeedUndo : 1
+    };
+    function isBoundaryNode(node,dir){
+        var tmp;
+        while(!domUtils.isBody(node)){
+            tmp = node;
+            node = node.parentNode;
+            if(tmp !== node[dir]){
+                return false;
+            }
+        }
+        return true;
+    }
+    me.addListener('keydown', function(type, evt) {
+        var rng = me.selection.getRange();
+
+        if(!rng.collapsed && !(evt.ctrlKey || evt.metaKey || evt.shiftKey || evt.altKey)){
+            var tmpNode = rng.startContainer;
+            if(domUtils.isFillChar(tmpNode)){
+                rng.setStartBefore(tmpNode)
+            }
+            tmpNode = rng.endContainer;
+            if(domUtils.isFillChar(tmpNode)){
+                rng.setEndAfter(tmpNode)
+            }
+            rng.txtToElmBoundary();
+            if(rng.startOffset == 0){
+                tmpNode = rng.startContainer;
+                if(isBoundaryNode(tmpNode,'firstChild')){
+                    tmpNode = rng.endContainer;
+                    if(rng.endOffset == rng.endContainer.childNodes.length && isBoundaryNode(tmpNode,'lastChild') ){
+                        me.fireEvent('saveScene');
+                        me.body.innerHTML = '<p>'+(browser.ie ? '' : '<br/>')+'</p>';
+                        rng.setStart(me.body.firstChild,0).setCursor(false,true);
+                        me.fireEvent('saveScene');
+                        browser.ie && me._selectionChange();
+                        return;
+                    }
+                }
+            }
+        }
+    });
+    //快捷键
+    me.addshortcutkey({
+         "selectAll" : "ctrl+65"
+    });
+};

+ 805 - 0
web/js/ueditor2/_src/plugins/serialize.js

@@ -0,0 +1,805 @@
+///import core
+///commands 定制过滤规则
+///commandsName  Serialize
+///commandsTitle  定制过滤规则
+UE.plugins['serialize'] = function () {
+    var ie = browser.ie,
+        version = browser.version;
+
+    function ptToPx(value){
+        return /pt/.test(value) ? value.replace( /([\d.]+)pt/g, function( str ) {
+            return  Math.round(parseFloat(str) * 96 / 72) + "px";
+        } ) : value;
+    }
+    var me = this, autoClearEmptyNode = me.options.autoClearEmptyNode,
+        EMPTY_TAG = dtd.$empty,
+        parseHTML = function () {
+            //干掉<a> 后便变得空格,保留</a>  这样的空格
+            var RE_PART = /<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\s\/>]+)\s*((?:(?:"[^"]*")|(?:'[^']*')|[^"'<>])*)\/?>))/g,
+                RE_ATTR = /([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g,
+                EMPTY_ATTR = {checked:1,compact:1,declare:1,defer:1,disabled:1,ismap:1,multiple:1,nohref:1,noresize:1,noshade:1,nowrap:1,readonly:1,selected:1},
+                CDATA_TAG = {script:1,style: 1},
+                NEED_PARENT_TAG = {
+                    "li": { "$": 'ul', "ul": 1, "ol": 1 },
+                    "dd": { "$": "dl", "dl": 1 },
+                    "dt": { "$": "dl", "dl": 1 },
+                    "option": { "$": "select", "select": 1 },
+                    "td": { "$": "tr", "tr": 1 },
+                    "th": { "$": "tr", "tr": 1 },
+                    "tr": { "$": "tbody", "tbody": 1, "thead": 1, "tfoot": 1, "table": 1 },
+                    "tbody": { "$": "table", 'table':1,"colgroup": 1 },
+                    "thead": { "$": "table", "table": 1 },
+                    "tfoot": { "$": "table", "table": 1 },
+                    "col": { "$": "colgroup","colgroup":1 }
+                };
+            var NEED_CHILD_TAG = {
+                "table": "td", "tbody": "td", "thead": "td", "tfoot": "td", //"tr": "td",
+                "colgroup": "col",
+                "ul": "li", "ol": "li",
+                "dl": "dd",
+                "select": "option"
+            };
+
+            function parse( html, callbacks ) {
+
+                var match,
+                    nextIndex = 0,
+                    tagName,
+                    cdata;
+                RE_PART.exec( "" );
+                while ( (match = RE_PART.exec( html )) ) {
+
+                    var tagIndex = match.index;
+                    if ( tagIndex > nextIndex ) {
+                        var text = html.slice( nextIndex, tagIndex );
+                        if ( cdata ) {
+                            cdata.push( text );
+                        } else {
+                            var isSpace=/^\s*$/.test(text);
+                            if(!isSpace){
+                            	callbacks.onText( text );
+                            }
+                        }
+                    }
+                    nextIndex = RE_PART.lastIndex;
+                    if ( (tagName = match[1]) ) {
+                        tagName = tagName.toLowerCase();
+                        if ( cdata && tagName == cdata._tag_name ) {
+                            callbacks.onCDATA( cdata.join( '' ) );
+                            cdata = null;
+                        }
+                        if ( !cdata ) {
+                            callbacks.onTagClose( tagName );
+                            continue;
+                        }
+                    }
+                    if ( cdata ) {
+                        cdata.push( match[0] );
+                        continue;
+                    }
+                    if ( (tagName = match[3]) ) {
+                        if ( /="/.test( tagName ) ) {
+                            continue;
+                        }
+                        tagName = tagName.toLowerCase();
+                        var attrPart = match[4],
+                            attrMatch,
+                            attrMap = {},
+                            selfClosing = attrPart && attrPart.slice( -1 ) == '/';
+                        if ( attrPart ) {
+                            RE_ATTR.exec( "" );
+                            while ( (attrMatch = RE_ATTR.exec( attrPart )) ) {
+                                var attrName = attrMatch[1].toLowerCase(),
+                                    attrValue = attrMatch[2] || attrMatch[3] || attrMatch[4] || '';
+                                if ( !attrValue && EMPTY_ATTR[attrName] ) {
+                                    attrValue = attrName;
+                                }
+                                if ( attrName == 'style' ) {
+                                    if ( ie && version <= 6 ) {
+                                        attrValue = attrValue.replace( /(?!;)\s*([\w-]+):/g, function ( m, p1 ) {
+                                            return p1.toLowerCase() + ':';
+                                        } );
+                                    }
+                                }
+                                //没有值的属性不添加
+                                if ( attrValue ) {
+                                    attrMap[attrName] = attrValue.replace( /:\s*/g, ':' )
+                                }
+
+                            }
+                        }
+                        callbacks.onTagOpen( tagName, attrMap, selfClosing );
+                        if ( !cdata && CDATA_TAG[tagName] ) {
+                            cdata = [];
+                            cdata._tag_name = tagName;
+                        }
+                        continue;
+                    }
+                    if ( (tagName = match[2]) ) {
+                        callbacks.onComment( tagName );
+                    }
+                }
+                if ( html.length > nextIndex ) {
+                    callbacks.onText( html.slice( nextIndex, html.length ) );
+                }
+            }
+
+            return function ( html, forceDtd ) {
+
+                var fragment = {
+                    type: 'fragment',
+                    parent: null,
+                    children: []
+                };
+                var currentNode = fragment;
+
+                function addChild( node ) {
+                    node.parent = currentNode;
+                    currentNode.children.push( node );
+                }
+
+                function addElement( element, open ) {
+                    var node = element;
+                    // 遇到结构化标签的时候
+                    if ( NEED_PARENT_TAG[node.tag] ) {
+                        // 考虑这种情况的时候, 结束之前的标签
+                        // e.g. <table><tr><td>12312`<tr>`4566
+                        while ( NEED_PARENT_TAG[currentNode.tag] && NEED_PARENT_TAG[currentNode.tag][node.tag] ) {
+                            currentNode = currentNode.parent;
+                        }
+                        // 如果前一个标签和这个标签是同一级, 结束之前的标签
+                        // e.g. <ul><li>123<li>
+                        if ( currentNode.tag == node.tag ) {
+                            currentNode = currentNode.parent;
+                        }
+                        // 向上补齐父标签
+                        while ( NEED_PARENT_TAG[node.tag] ) {
+                            if ( NEED_PARENT_TAG[node.tag][currentNode.tag] ) break;
+                            node = node.parent = {
+                                type: 'element',
+                                tag: NEED_PARENT_TAG[node.tag]['$'],
+                                attributes: {},
+                                children: [node]
+                            };
+                        }
+                    }
+                    if ( forceDtd ) {
+                        // 如果遇到这个标签不能放在前一个标签内部,则结束前一个标签,span单独处理
+                        while ( dtd[node.tag] && !(currentNode.tag == 'span' ? utils.extend( dtd['strong'], {'a':1,'A':1} ) : (dtd[currentNode.tag] || dtd['div']))[node.tag] ) {
+                            if ( tagEnd( currentNode ) ) continue;
+                            if ( !currentNode.parent ) break;
+                            currentNode = currentNode.parent;
+                        }
+                    }
+                    node.parent = currentNode;
+                    currentNode.children.push( node );
+                    if ( open ) {
+                        currentNode = element;
+                    }
+                    if ( element.attributes.style ) {
+                        element.attributes.style = element.attributes.style.toLowerCase();
+                    }
+                    return element;
+                }
+
+                // 结束一个标签的时候,需要判断一下它是否缺少子标签
+                // e.g. <table></table>
+                function tagEnd( node ) {
+                    var needTag;
+                    if ( !node.children.length && (needTag = NEED_CHILD_TAG[node.tag]) ) {
+                        addElement( {
+                            type: 'element',
+                            tag: needTag,
+                            attributes: {},
+                            children: []
+                        }, true );
+                        return true;
+                    }
+                    return false;
+                }
+                parse( html, {
+                    onText: function ( text ) {
+                        while ( !(dtd[currentNode.tag] || dtd['div'])['#'] ) {
+                            if ( tagEnd( currentNode ) ) continue;
+                            currentNode = currentNode.parent;
+                        }
+                        addChild( {
+                            type: 'text',
+                            data: text
+                        } );
+                    },
+                    onComment: function ( text ) {
+                        addChild( {
+                            type: 'comment',
+                            data: text
+                        } );
+                    },
+                    onCDATA: function ( text ) {
+                        while ( !(dtd[currentNode.tag] || dtd['div'])['#'] ) {
+                            if ( tagEnd( currentNode ) ) continue;
+                            currentNode = currentNode.parent;
+                        }
+                        addChild( {
+                            type: 'cdata',
+                            data: text
+                        } );
+                    },
+                    onTagOpen: function ( tag, attrs, closed ) {
+                        closed = closed || EMPTY_TAG[tag] ;
+                        addElement( {
+                            type: 'element',
+                            tag: tag,
+                            attributes: attrs,
+                            closed: closed,
+                            children: []
+                        }, !closed );
+                    },
+                    onTagClose: function ( tag ) {
+                        var node = currentNode;
+                        // 向上找匹配的标签, 这里不考虑dtd的情况是因为tagOpen的时候已经处理过了, 这里不会遇到
+                        while ( node && tag != node.tag ) {
+                            node = node.parent;
+                        }
+                        if ( node ) {
+                            // 关闭中间的标签
+                            for ( var tnode = currentNode; tnode !== node.parent; tnode = tnode.parent ) {
+                                tagEnd( tnode );
+                            }
+                            //去掉空白的inline节点
+                            //分页,锚点保留
+                            //|| dtd.$removeEmptyBlock[node.tag])
+//                                if ( !node.children.length && dtd.$removeEmpty[node.tag] && !node.attributes.anchorname && node.attributes['class'] != 'pagebreak' && node.tag != 'a') {
+//
+//                                    node.parent.children.pop();
+//                                }
+                            currentNode = node.parent;
+                        } else {
+                            // 如果没有找到开始标签, 则创建新标签
+                            // eg. </div> => <div></div>
+                            //针对视屏网站embed会给结束符,这里特殊处理一下
+                            if ( !(dtd.$removeEmpty[tag] || dtd.$removeEmptyBlock[tag] || tag == 'embed') ) {
+                                node = {
+                                    type: 'element',
+                                    tag: tag,
+                                    attributes: {},
+                                    children: []
+                                };
+                                addElement( node, true );
+                                tagEnd( node );
+                                currentNode = node.parent;
+                            }
+
+
+                        }
+                    }
+                } );
+                // 处理这种情况, 只有开始标签没有结束标签的情况, 需要关闭开始标签
+                // eg. <table>
+                while ( currentNode !== fragment ) {
+                    tagEnd( currentNode );
+                    currentNode = currentNode.parent;
+                }
+                return fragment;
+            };
+        }();
+    var unhtml1 = function () {
+        var map = { '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };
+
+        function rep( m ) {
+            return map[m];
+        }
+
+        return function ( str ) {
+            str = str + '';
+            return str ? str.replace( /[<>"']/g, rep ) : '';
+        };
+    }();
+    var toHTML = function () {
+        function printChildren( node, pasteplain ) {
+            var children = node.children;
+
+            var buff = [];
+            for ( var i = 0,ci; ci = children[i]; i++ ) {
+
+                buff.push( toHTML( ci, pasteplain ) );
+            }
+            return buff.join( '' );
+        }
+
+        function printAttrs( attrs ) {
+            var buff = [];
+            for ( var k in attrs ) {
+                var value = attrs[k];
+
+                if(k == 'style'){
+
+                    //pt==>px
+                    value = ptToPx(value);
+                    //color rgb ==> hex
+                    if(/rgba?\s*\([^)]*\)/.test(value)){
+                        value = value.replace( /rgba?\s*\(([^)]*)\)/g, function( str ) {
+                            return utils.fixColor('color',str);
+                        } )
+                    }
+                    //过滤掉所有的white-space,在纯文本编辑器里粘贴过来的内容,到chrome中会带有span和white-space属性,导致出现不能折行的情况
+                    //所以在这里去掉这个属性
+                    attrs[k] = utils.optCss(value.replace(/windowtext/g,'#000'))
+                        .replace(/white-space[^;]+;/g,'');
+                    if(!attrs[k]){
+                        continue;
+                    }
+                }
+
+                buff.push( k + '="' + unhtml1( attrs[k] ) + '"' );
+            }
+            return buff.join( ' ' )
+        }
+
+        function printData( node, notTrans ) {
+            //trace:1399 输入html代码时空格转换成为&nbsp;
+            //node.data.replace(/&nbsp;/g,' ') 针对pre中的空格和出现的&nbsp;把他们在得到的html代码中都转换成为空格,为了在源码模式下显示为空格而不是&nbsp;
+            return notTrans ? node.data.replace(/&nbsp;/g,' ') : unhtml1( node.data ).replace(/ /g,'&nbsp;');
+        }
+
+        //纯文本模式下标签转换
+        var transHtml = {
+            'li':'p',
+            'h1':'p','h2':'p','h3':'p','h4':'p','h5':'p','h6':'p',
+            'tr':'p',
+            'br':'br',
+            'div':'p',
+            'p':'p'//trace:1398 碰到p标签自己要加上p,否则transHtml[tag]是undefined
+        };
+        var clearTagName ={
+            'table':1,
+            'tbody':1,
+            'ol':1,
+            'ul':1,
+            'dt':1
+        }
+        function printElement( node, pasteplain ) {
+            if ( node.type == 'element' && !node.children.length && (dtd.$removeEmpty[node.tag]) && node.tag != 'a' && utils.isEmptyObject(node.attributes) && autoClearEmptyNode) {// 锚点保留
+                return html;
+            }
+            var tag = node.tag;
+            if ( pasteplain && tag == 'td' ) {
+                if ( !html ) html = '';
+                html += printChildren( node, pasteplain ) + '&nbsp;&nbsp;&nbsp;';
+            } else {
+                var attrs = printAttrs( node.attributes );
+
+                var html = pasteplain && clearTagName[tag] ? '' :
+                    '<' + (pasteplain && transHtml[tag] !==undefined? transHtml[tag] : tag) + (attrs ? ' ' + attrs : '') + (EMPTY_TAG[tag] ? ' />' : '>');
+                if ( !EMPTY_TAG[tag] ) {
+                    //trace:1627 ,2070
+                    //p标签为空,将不占位这里占位符不起作用,用&nbsp;或者br
+                    if( tag == 'p' && !node.children.length){
+                        html += browser.ie ? '&nbsp;' : '<br/>';
+                    }
+                    html += printChildren( node, pasteplain );
+                    html +=(pasteplain && clearTagName[tag] ? '' : '</' + (pasteplain && transHtml[tag]!==undefined? transHtml[tag] : tag) + '>');
+                }
+            }
+
+            return html;
+        }
+
+        return function ( node, pasteplain ) {
+            if ( node.type == 'fragment' ) {
+                return printChildren( node, pasteplain );
+            } else if ( node.type == 'element' ) {
+                return printElement( node, pasteplain );
+            } else if ( node.type == 'text' || node.type == 'cdata' ) {
+                return printData( node, dtd.$notTransContent[node.parent.tag] );
+            } else if ( node.type == 'comment' ) {
+                return '<!--' + node.data + '-->';
+            }
+            return '';
+        };
+    }();
+
+    var NODE_NAME_MAP = {
+        'text': '#text',
+        'comment': '#comment',
+        'cdata': '#cdata-section',
+        'fragment': '#document-fragment'
+    };
+
+
+    //写入编辑器时,调用,进行转换操作
+    function transNode( node, word_img_flag ) {
+
+        var sizeMap = [0, 10, 12, 16, 18, 24, 32, 48],
+            attr,
+            indexOf = utils.indexOf;
+        switch ( node.tag ) {
+            case 'script':
+                node.tag = 'div';
+                node.attributes._ue_org_tagName = 'script';
+                node.attributes._ue_div_script = 1;
+                node.attributes._ue_script_data = node.children[0] ? encodeURIComponent(node.children[0].data)  : '';
+                node.attributes._ue_custom_node_ = 1;
+                node.children = [];
+                break;
+            case 'style':
+                node.tag = 'div';
+                node.attributes._ue_div_style = 1;
+                node.attributes._ue_org_tagName = 'style';
+                node.attributes._ue_style_data = node.children[0] ? encodeURIComponent(node.children[0].data)  : '';
+                node.attributes._ue_custom_node_ = 1;
+                node.children = [];
+                break;
+            case 'img':
+                //todo base64暂时去掉,后边做远程图片上传后,干掉这个
+                if(node.attributes.src && /^data:/.test(node.attributes.src)){
+                    return {
+                        type : 'fragment',
+                        children:[]
+                    }
+                }
+                if ( node.attributes.src && /^(?:file)/.test( node.attributes.src ) ) {
+                    if ( !/(gif|bmp|png|jpg|jpeg)$/.test( node.attributes.src ) ) {
+                        return {
+                            type : 'fragment',
+                            children:[]
+                        }
+                    }
+                    node.attributes.word_img = node.attributes.src;
+                    node.attributes.src = me.options.UEDITOR_HOME_URL + 'themes/default/images/spacer.gif';
+                    var flag = parseInt(node.attributes.width)<128||parseInt(node.attributes.height)<43;
+                    node.attributes.style="background:url(" + (flag? me.options.themePath+me.options.theme +"/images/word.gif":me.options.langPath+me.options.lang + "/images/localimage.png")+") no-repeat center center;border:1px solid #ddd";
+                    //node.attributes.style = 'width:395px;height:173px;';
+                    word_img_flag && (word_img_flag.flag = 1);
+                }
+                if(browser.ie && browser.version < 7 )
+                    node.attributes.orgSrc = node.attributes.src;
+                node.attributes.data_ue_src = node.attributes.data_ue_src || node.attributes.src;
+                break;
+            case 'li':
+                var child = node.children[0];
+
+                if ( !child || child.type != 'element' || child.tag != 'p' && dtd.p[child.tag] ) {
+                    var tmpPNode = {
+                        type: 'element',
+                        tag: 'p',
+                        attributes: {},
+
+                        parent : node
+                    };
+                    tmpPNode.children = child ? node.children :[
+                        browser.ie ? {
+                            type:'text',
+                            data:domUtils.fillChar,
+                            parent : tmpPNode
+
+                        }:
+                        {
+                            type : 'element',
+                            tag : 'br',
+                            attributes:{},
+                            closed: true,
+                            children: [],
+                            parent : tmpPNode
+                        }
+                    ];
+                    node.children =   [tmpPNode];
+                }
+                break;
+            case 'table':
+            case 'td':
+                optStyle( node );
+                break;
+            case 'a'://锚点,a==>img
+                if ( node.attributes['anchorname'] ) {
+                    node.tag = 'img';
+                    node.attributes = {
+                        'class' : 'anchorclass',
+                        'anchorname':node.attributes['name']
+                    };
+                    node.closed = 1;
+                }
+                node.attributes.href && (node.attributes.data_ue_src = node.attributes.href);
+                break;
+            case 'b':
+                node.tag = node.name = 'strong';
+                break;
+            case 'i':
+                node.tag = node.name = 'em';
+                break;
+            case 'u':
+                node.tag = node.name = 'span';
+                node.attributes.style = (node.attributes.style || '') + ';text-decoration:underline;';
+                break;
+            case 's':
+            case 'del':
+                node.tag = node.name = 'span';
+                node.attributes.style = (node.attributes.style || '') + ';text-decoration:line-through;';
+                if ( node.children.length == 1 ) {
+                    child = node.children[0];
+                    if ( child.tag == node.tag ) {
+                        node.attributes.style += ";" + child.attributes.style;
+                        node.children = child.children;
+
+                    }
+                }
+                break;
+            case 'span':
+
+                var style = node.attributes.style;
+                if ( style ) {
+                    if ( !node.attributes.style  || browser.webkit && style == "white-space:nowrap;") {
+                        delete node.attributes.style;
+                    }
+                }
+
+                //针对ff3.6span的样式不能正确继承的修复
+
+                if(browser.gecko && browser.version <= 10902 && node.parent){
+                    var parent = node.parent;
+                    if(parent.tag == 'span' && parent.attributes && parent.attributes.style){
+                        node.attributes.style = parent.attributes.style + ';' + node.attributes.style;
+                    }
+                }
+                if ( utils.isEmptyObject( node.attributes ) && autoClearEmptyNode) {
+                    node.type = 'fragment'
+                }
+                break;
+            case 'font':
+                node.tag = node.name = 'span';
+                attr = node.attributes;
+                node.attributes = {
+                    'style': (attr.size ? 'font-size:' + (sizeMap[attr.size] || 12) + 'px' : '')
+                        + ';' + (attr.color ? 'color:'+ attr.color : '')
+                        + ';' + (attr.face ? 'font-family:'+ attr.face : '')
+                        + ';' + (attr.style||'')
+                };
+
+                while(node.parent.tag == node.tag && node.parent.children.length == 1){
+                    node.attributes.style && (node.parent.attributes.style ? (node.parent.attributes.style += ";" + node.attributes.style) : (node.parent.attributes.style = node.attributes.style));
+                    node.parent.children = node.children;
+                    node = node.parent;
+
+                }
+                break;
+            case 'p':
+                if ( node.attributes.align ) {
+                    node.attributes.style = (node.attributes.style || '') + ';text-align:' +
+                        node.attributes.align + ';';
+                    delete node.attributes.align;
+                }
+
+        }
+        return node;
+    }
+
+    function optStyle( node ) {
+        if ( ie && node.attributes.style ) {
+            var style = node.attributes.style;
+            node.attributes.style = style.replace(/;\s*/g,';');
+            node.attributes.style = node.attributes.style.replace( /^\s*|\s*$/, '' )
+        }
+    }
+    //getContent调用转换
+    function transOutNode( node ) {
+
+        switch ( node.tag ) {
+            case 'div' :
+                if(node.attributes._ue_div_script){
+                    node.tag = 'script';
+                    node.children = [{type:'cdata',data:node.attributes._ue_script_data?decodeURIComponent(node.attributes._ue_script_data):'',parent:node}];
+                    delete node.attributes._ue_div_script;
+                    delete node.attributes._ue_script_data;
+                    delete node.attributes._ue_custom_node_;
+                    delete node.attributes._ue_org_tagname;
+
+                }
+                if(node.attributes._ue_div_style){
+                    node.tag = 'style';
+                    node.children = [{type:'cdata',data:node.attributes._ue_style_data?decodeURIComponent(node.attributes._ue_style_data):'',parent:node}];
+                    delete node.attributes._ue_div_style;
+                    delete node.attributes._ue_style_data;
+                    delete node.attributes._ue_custom_node_;
+                    delete node.attributes._ue_org_tagname;
+
+                }
+                break;
+            case 'table':
+                !node.attributes.style && delete node.attributes.style;
+                if ( ie && node.attributes.style ) {
+
+                    optStyle( node );
+                }
+                break;
+            case 'td':
+            case 'th':
+                if ( /display\s*:\s*none/i.test( node.attributes.style ) ) {
+                    return {
+                        type: 'fragment',
+                        children: []
+                    };
+                }
+                if ( ie && !node.children.length ) {
+                    var txtNode = {
+                        type: 'text',
+                        data:domUtils.fillChar,
+                        parent : node
+                    };
+                    node.children[0] = txtNode;
+                }
+                if ( ie && node.attributes.style ) {
+                    optStyle( node );
+                }
+                break;
+            case 'img'://锚点,img==>a
+                if ( node.attributes.anchorname ) {
+                    node.tag = 'a';
+                    node.attributes = {
+                        name : node.attributes.anchorname,
+                        anchorname : 1
+                    };
+                    node.closed = null;
+                }else{
+                    if(node.attributes.data_ue_src){
+                        node.attributes.src = node.attributes.data_ue_src;
+                        delete node.attributes.data_ue_src;
+                    }
+                }
+                break;
+
+            case 'a':
+                if(node.attributes.data_ue_src){
+                    node.attributes.href = node.attributes.data_ue_src;
+                    delete node.attributes.data_ue_src;
+                }
+        }
+
+        return node;
+    }
+
+    function childrenAccept( node, visit, ctx ) {
+
+        if ( !node.children || !node.children.length ) {
+            return node;
+        }
+        var children = node.children;
+        for ( var i = 0; i < children.length; i++ ) {
+            var newNode = visit( children[i], ctx );
+            if ( newNode.type == 'fragment' ) {
+                var args = [i, 1];
+                args.push.apply( args, newNode.children );
+                children.splice.apply( children, args );
+                //节点为空的就干掉,不然后边的补全操作会添加多余的节点
+                if ( !children.length ) {
+                    node = {
+                        type: 'fragment',
+                        children: []
+                    }
+                }
+                i --;
+            } else {
+                children[i] = newNode;
+            }
+        }
+        return node;
+    }
+
+    function Serialize( rules ) {
+        this.rules = rules;
+    }
+
+
+    Serialize.prototype = {
+        // NOTE: selector目前只支持tagName
+        rules: null,
+        // NOTE: node必须是fragment
+        filter: function ( node, rules, modify ) {
+            rules = rules || this.rules;
+            var whiteList = rules && rules.whiteList;
+            var blackList = rules && rules.blackList;
+
+            function visitNode( node, parent ) {
+                node.name = node.type == 'element' ?
+                    node.tag : NODE_NAME_MAP[node.type];
+                if ( parent == null ) {
+                    return childrenAccept( node, visitNode, node );
+                }
+
+                if ( blackList && (blackList[node.name]|| (node.attributes && node.attributes._ue_org_tagName && blackList[node.attributes._ue_org_tagName]))) {
+                    modify && (modify.flag = 1);
+                    return {
+                        type: 'fragment',
+                        children: []
+                    };
+                }
+                if ( whiteList ) {
+                    if ( node.type == 'element' ) {
+                        if ( parent.type == 'fragment' ? whiteList[node.name] : whiteList[node.name] && whiteList[parent.name][node.name] ) {
+
+                            var props;
+                            if ( (props = whiteList[node.name].$) ) {
+                                var oldAttrs = node.attributes;
+                                var newAttrs = {};
+                                for ( var k in props ) {
+                                    if ( oldAttrs[k] ) {
+                                        newAttrs[k] = oldAttrs[k];
+                                    }
+                                }
+                                node.attributes = newAttrs;
+                            }
+
+
+                        } else {
+                            modify && (modify.flag = 1);
+                            node.type = 'fragment';
+                            // NOTE: 这里算是一个hack
+                            node.name = parent.name;
+                        }
+                    } else {
+                        // NOTE: 文本默认允许
+                    }
+                }
+                if ( blackList || whiteList ) {
+                    childrenAccept( node, visitNode, node );
+                }
+                return node;
+            }
+
+            return visitNode( node, null );
+        },
+        transformInput: function ( node, word_img_flag ) {
+
+            function visitNode( node ) {
+                node = transNode( node, word_img_flag );
+
+                node = childrenAccept( node, visitNode, node );
+
+                if ( me.options.pageBreakTag && node.type == 'text' && node.data.replace( /\s/g, '' ) == me.options.pageBreakTag ) {
+
+                    node.type = 'element';
+                    node.name = node.tag = 'hr';
+
+                    delete node.data;
+                    node.attributes = {
+                        'class' : 'pagebreak',
+                        noshade:"noshade",
+                        size:"5",
+                        'unselectable' : 'on',
+                        'style' : 'moz-user-select:none;-khtml-user-select: none;'
+                    };
+
+                    node.children = [];
+
+                }
+                //去掉多余的空格和换行
+                if(node.type == 'text' && !dtd.$notTransContent[node.parent.tag]){
+                    node.data = node.data.replace(/[\r\t\n]*/g,'')//.replace(/[ ]*$/g,'')
+                }
+                return node;
+            }
+
+            return visitNode( node );
+        },
+        transformOutput: function ( node ) {
+            function visitNode( node ) {
+
+                if ( node.tag == 'hr' && node.attributes['class'] == 'pagebreak' ) {
+                    delete node.tag;
+                    node.type = 'text';
+                    node.data = me.options.pageBreakTag;
+                    delete node.children;
+
+                }
+                node = transOutNode( node );
+                node = childrenAccept( node, visitNode, node );
+                return node;
+            }
+
+            return visitNode( node );
+        },
+        toHTML: toHTML,
+        parseHTML: parseHTML,
+        word: UE.filterWord
+    };
+    me.serialize = new Serialize( me.options.serialize || {});
+    UE.serialize = new Serialize( {} );
+};

+ 14 - 0
web/js/ueditor2/_src/plugins/signset.js

@@ -0,0 +1,14 @@
+UE.commands['signset'] = {
+    execCommand : function(){
+    	alert('123');
+    },
+	queryCommandState:function(){
+	     var images = this.document.getElementsByTagName("img" );
+	     for(var i=0;i<$(images).length;i++){
+	     	if($(images[i]).css("width")!="100px"){
+	     		return 0;	 //如果找到宽度不为100的图片,则返回0,代表当前按钮可以点击
+	     	}
+	     }
+	     return -1;           //否则返回-1,告诉编辑器将当前按钮置灰
+	}
+};

+ 68 - 0
web/js/ueditor2/_src/plugins/snapscreen.js

@@ -0,0 +1,68 @@
+///import core
+///import plugins\inserthtml.js
+///import plugins\image.js
+///commandsName  snapscreen
+///commandsTitle  截屏
+/**
+ * 截屏插件
+ */
+UE.plugins['snapscreen'] = function(){
+    var me = this,
+        doc,
+        snapplugin;
+    me.addListener("ready",function(){
+        var container = me.container;
+        doc = container.ownerDocument || container.document;
+        snapplugin = doc.createElement("object");
+        snapplugin.type = "application/x-pluginbaidusnap";
+        snapplugin.style.cssText = "position:absolute;left:-9999px;";
+        snapplugin.setAttribute("width","0");
+        snapplugin.setAttribute("height","0");
+        container.appendChild(snapplugin);
+    });
+    me.commands['snapscreen'] = {
+        execCommand: function(){
+            var me = this,lang = me.getLang("snapScreen_plugin");
+            me.setOpt({
+                  snapscreenServerPort: 80                                    //屏幕截图的server端端口
+                 ,snapscreenImgAlign: ''                                //截图的图片默认的排版方式
+           });
+           var editorOptions = me.options;
+
+            var onSuccess = function(rs){
+                try{
+                    rs = eval("("+ rs +")");
+                }catch(e){
+                    alert(lang.callBackErrorMsg);
+                    return;
+                }
+
+                if(rs.state != 'SUCCESS'){
+                    alert(rs.state);
+                    return;
+                }
+                me.execCommand('insertimage', {
+                    src: editorOptions.snapscreenPath + rs.url,
+                    floatStyle: editorOptions.snapscreenImgAlign,
+                    data_ue_src:editorOptions.snapscreenPath + rs.url
+                });
+            };
+            var onStartUpload = function(){
+                //开始截图上传
+            };
+            var onError = function(){
+                alert(lang.uploadErrorMsg);
+            };
+            try{
+                var ret =snapplugin.saveSnapshot(editorOptions.snapscreenHost, editorOptions.snapscreenServerUrl, editorOptions.snapscreenServerPort.toString());
+                onSuccess(ret);
+            }catch(e){
+                me.ui._dialogs['snapscreenDialog'].open();
+            }
+        },
+        queryCommandState: function(){
+            return this.highlight ? -1 :0;
+        }
+    };
+}
+

+ 352 - 0
web/js/ueditor2/_src/plugins/source.js

@@ -0,0 +1,352 @@
+///import core
+///import plugins/serialize.js
+///import plugins/undo.js
+///commands 查看源码
+///commandsName  Source
+///commandsTitle  查看源码
+(function (){
+    function SourceFormater(config){
+        config = config || {};
+        this.indentChar = config.indentChar || '    ';
+        this.breakChar = config.breakChar || '\n';
+        this.selfClosingEnd = config.selfClosingEnd || ' />';
+    }
+    var unhtml1 = function (){
+        var map = { '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };
+        function rep( m ){ return map[m]; }
+        return function ( str ) {
+            str = str + '';
+            return str ? str.replace( /[<>"']/g, rep ) : '';
+        };
+    }();
+    var inline = utils.extend({a:1,A:1},dtd.$inline,true);
+
+
+    function printAttrs(attrs){
+        var buff = [];
+        for (var k in attrs) {
+            buff.push(k + '="' + unhtml1(attrs[k]) + '"');
+        }
+        return buff.join(' ');
+    }
+    SourceFormater.prototype = {
+        format: function (html){
+            var node = UE.serialize.parseHTML(html);
+            this.buff = [];
+            this.indents = '';
+            this.indenting = 1;
+            this.visitNode(node);
+            return this.buff.join('');
+        },
+        visitNode: function (node){
+            if (node.type == 'fragment') {
+                this.visitChildren(node.children);
+            } else if (node.type == 'element') {
+                var selfClosing = dtd.$empty[node.tag];
+                this.visitTag(node.tag, node.attributes, selfClosing);
+
+                this.visitChildren(node.children);
+
+                if (!selfClosing) {
+                    this.visitEndTag(node.tag);
+                }
+            } else if (node.type == 'comment') {
+                this.visitComment(node.data);
+            } else {
+                this.visitText(node.data,dtd.$notTransContent[node.parent.tag]);
+            }
+        },
+        visitChildren: function (children){
+            for (var i=0; i<children.length; i++) {
+                this.visitNode(children[i]);
+            }
+        },
+        visitTag: function (tag, attrs, selfClosing){
+            if (this.indenting) {
+                this.indent();
+            } else if (!inline[tag]) { // todo: 去掉a, 因为dtd的inline里面没有a
+                this.newline();
+                this.indent();
+            }
+            this.buff.push('<', tag);
+            var attrPart = printAttrs(attrs);
+            if (attrPart) {
+                this.buff.push(' ', attrPart);
+            }
+            if (selfClosing) {
+                this.buff.push(this.selfClosingEnd);
+                if (tag == 'br') {
+                    this.newline();
+                }
+            } else {
+                this.buff.push('>');
+                this.indents += this.indentChar;
+            }
+            if (!inline[tag]) {
+                this.newline();
+            }
+        },
+        indent: function (){
+            this.buff.push(this.indents);
+            this.indenting = 0;
+        },
+        newline: function (){
+            this.buff.push(this.breakChar);
+            this.indenting = 1;
+        },
+        visitEndTag: function (tag){
+            
+            this.indents = this.indents.slice(0, -this.indentChar.length);
+            if (this.indenting) {
+                this.indent();
+            } else if (!inline[tag]) {
+                this.newline();
+                this.indent();
+            }
+            this.buff.push('</', tag, '>');
+        },
+        visitText: function (text,notTrans){
+            if (this.indenting) {
+                this.indent();
+            }
+      
+//            if(!notTrans){
+//                 text = text.replace(/&nbsp;/g, ' ').replace(/[ ][ ]+/g, function (m){
+//                    return new Array(m.length + 1).join('&nbsp;');
+//                }).replace(/(?:^ )|(?: $)/g, '&nbsp;');
+//            }
+            text = text.replace(/&nbsp;/g, ' ');
+            this.buff.push(text);
+
+        },
+        visitComment: function (text){
+            if (this.indenting) {
+                this.indent();
+            }
+            this.buff.push('<!--', text, '-->');
+        }
+    };
+
+    var sourceEditors = {
+        textarea: function (editor, holder){
+            var textarea = holder.ownerDocument.createElement('textarea');
+            textarea.style.cssText = 'position:absolute;resize:none;width:100%;height:100%;border:0;padding:0;margin:0;overflow-y:auto;';
+            // todo: IE下只有onresize属性可用... 很纠结
+            if (browser.ie && browser.version < 8) {
+                textarea.style.width = holder.offsetWidth + 'px';
+                textarea.style.height = holder.offsetHeight + 'px';
+                holder.onresize = function (){
+                    textarea.style.width = holder.offsetWidth + 'px';
+                    textarea.style.height = holder.offsetHeight + 'px';
+                };
+            }
+            holder.appendChild(textarea);
+            return {
+                setContent: function (content){
+                    textarea.value = content;
+                },
+                getContent: function (){
+                    return textarea.value;
+                },
+                select: function (){
+                    var range;
+                    if (browser.ie) {
+                        range = textarea.createTextRange();
+                        range.collapse(true);
+                        range.select();
+                    } else {
+                        //todo: chrome下无法设置焦点
+                        textarea.setSelectionRange(0, 0);
+                        textarea.focus();
+                    }
+                },
+                dispose: function (){
+                    holder.removeChild(textarea);
+                    // todo
+                    holder.onresize = null;
+                    textarea = null;
+                    holder = null;
+                }
+            };
+        },
+        codemirror: function (editor, holder){
+
+            var codeEditor = window.CodeMirror(holder, {
+                mode: "text/html",
+                tabMode: "indent",
+                lineNumbers: true,
+                lineWrapping:true
+            });
+            var dom = codeEditor.getWrapperElement();
+            dom.style.cssText = 'position:absolute;left:0;top:0;width:100%;height:100%;font-family:consolas,"Courier new",monospace;font-size:13px;';
+            codeEditor.getScrollerElement().style.cssText = 'position:absolute;left:0;top:0;width:100%;height:100%;';
+            codeEditor.refresh();
+            return {
+                getCodeMirror:function(){
+                    return codeEditor;
+                },
+                setContent: function (content){
+                    codeEditor.setValue(content);
+                },
+                getContent: function (){
+                    return codeEditor.getValue();
+                },
+                select: function (){
+                    codeEditor.focus();
+                },
+                dispose: function (){
+                    holder.removeChild(dom);
+                    dom = null;
+                    codeEditor = null;
+                }
+            };
+        }
+    };
+
+    UE.plugins['source'] = function (){
+        var me = this;
+        var opt = this.options;
+        var formatter = new SourceFormater(opt.source);
+        var sourceMode = false;
+        var sourceEditor;
+
+        opt.sourceEditor = browser.ie  ? 'textarea' : (opt.sourceEditor || 'codemirror');
+
+        me.setOpt({
+            sourceEditorFirst:false
+        });
+        function createSourceEditor(holder){
+            return sourceEditors[opt.sourceEditor == 'codemirror' && window.CodeMirror ? 'codemirror' : 'textarea'](me, holder);
+        }
+
+        var bakCssText;
+        //解决在源码模式下getContent不能得到最新的内容问题
+        var oldGetContent = me.getContent,
+            bakAddress;
+
+        me.commands['source'] = {
+            execCommand: function (){
+
+                sourceMode = !sourceMode;
+                if (sourceMode) {
+                    bakAddress = me.selection.getRange().createAddress(false,true);
+                    me.undoManger && me.undoManger.save(true);
+                    if(browser.gecko){
+                        me.body.contentEditable = false;
+                    }
+
+                    bakCssText = me.iframe.style.cssText;
+                    me.iframe.style.cssText += 'position:absolute;left:-32768px;top:-32768px;';
+
+                    var content = formatter.format(me.hasContents() ? me.getContent() : '');
+
+                    sourceEditor = createSourceEditor(me.iframe.parentNode);
+
+                    sourceEditor.setContent(content);
+                    setTimeout(function (){
+                        sourceEditor.select();
+                        me.addListener('fullscreenchanged', function(){
+                            try{
+                                sourceEditor.getCodeMirror().refresh()
+                            }catch(e){}
+                        });
+                    });
+                    //重置getContent,源码模式下取值也能是最新的数据
+                    me.getContent = function (){
+                        var cont = sourceEditor.getContent() || '<p>' + (browser.ie ? '' : '<br/>')+'</p>';
+                        return cont.replace(/>[\n\r\t]+([ ]{4})+/g,'>').replace(/[\n\r\t]+([ ]{4})+</g,'<').replace(/>[\n\r\t]+</g,'><');
+                    };
+                } else {
+                    me.iframe.style.cssText = bakCssText;
+                    var cont = sourceEditor.getContent() || '<p>' + (browser.ie ? '' : '<br/>')+'</p>';
+                    cont = cont.replace(/>[\n\r\t]+([ ]{4})+/g,'>').replace(/[\n\r\t]+([ ]{4})+</g,'<').replace(/>[\n\r\t]+</g,'><');
+                    me.setContent(cont);
+                    sourceEditor.dispose();
+                    sourceEditor = null;
+                    //还原getContent方法
+                    me.getContent = oldGetContent;
+                    var first = me.body.firstChild;
+                    //trace:1106 都删除空了,下边会报错,所以补充一个p占位
+                    if(!first){
+                        me.body.innerHTML = '<p>'+(browser.ie?'':'<br/>')+'</p>';
+                        first = me.body.firstChild;
+                    }
+                    //要在ifm为显示时ff才能取到selection,否则报错
+                    //这里不能比较位置了
+                    me.undoManger && me.undoManger.save(true);
+
+                    if(browser.gecko){
+
+                        var input = document.createElement('input');
+                        input.style.cssText = 'position:absolute;left:0;top:-32768px';
+
+                        document.body.appendChild(input);
+
+                        me.body.contentEditable = false;
+                        setTimeout(function(){
+                            domUtils.setViewportOffset(input, { left: -32768, top: 0 });
+                            input.focus();
+                            setTimeout(function(){
+                                me.body.contentEditable = true;
+                                me.selection.getRange().moveToAddress(bakAddress).select();
+                                domUtils.remove(input);
+                            });
+
+                        });
+                    }else{
+                        //ie下有可能报错,比如在代码顶头的情况
+                        try{
+                            me.selection.getRange().moveToAddress(bakAddress).select();
+                        }catch(e){}
+
+                    }
+                }
+                this.fireEvent('sourcemodechanged', sourceMode);
+            },
+            queryCommandState: function (){
+                return sourceMode|0;
+            },
+            notNeedUndo : 1
+        };
+        var oldQueryCommandState = me.queryCommandState;
+
+        me.queryCommandState = function (cmdName){
+            cmdName = cmdName.toLowerCase();
+            if (sourceMode) {
+                //源码模式下可以开启的命令
+                return cmdName in {
+                    'source' : 1,
+                    'fullscreen' : 1
+                } ? 1 : -1
+            }
+            return oldQueryCommandState.apply(this, arguments);
+        };
+
+        if(opt.sourceEditor == "codemirror"){
+
+            me.addListener("ready",function(){
+                utils.loadFile(document,{
+                    src : opt.codeMirrorJsUrl || opt.UEDITOR_HOME_URL + "third-party/codemirror/codemirror.js",
+                    tag : "script",
+                    type : "text/javascript",
+                    defer : "defer"
+                },function(){
+                    if(opt.sourceEditorFirst){
+                        setTimeout(function(){
+                            me.execCommand("source");
+                        },0);
+                    }
+                });
+                utils.loadFile(document,{
+                    tag : "link",
+                    rel : "stylesheet",
+                    type : "text/css",
+                    href : opt.codeMirrorCssUrl || opt.UEDITOR_HOME_URL + "third-party/codemirror/codemirror.css"
+                });
+
+            });
+        }
+
+    };
+
+})();

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3044 - 0
web/js/ueditor2/_src/plugins/table.js


+ 39 - 0
web/js/ueditor2/_src/plugins/template.js

@@ -0,0 +1,39 @@
+///import core
+///import plugins\inserthtml.js
+///import plugins\cleardoc.js
+///commands 模板
+///commandsName  template
+///commandsTitle  模板
+///commandsDialog  dialogs\template
+UE.plugins['template'] = function () {
+    UE.commands['template'] = {
+        execCommand:function (cmd, obj) {
+            obj.html && this.execCommand("inserthtml", obj.html);
+        }
+    };
+    this.addListener("click", function (type, evt) {
+        var el = evt.target || evt.srcElement,
+            range = this.selection.getRange();
+        var tnode = domUtils.findParent(el, function (node) {
+            if (node.className && domUtils.hasClass(node, "ue_t")) {
+                return node;
+            }
+        }, true);
+        tnode && range.selectNode(tnode).shrinkBoundary().select();
+    });
+    this.addListener("keydown", function (type, evt) {
+        var range = this.selection.getRange();
+        if (!range.collapsed) {
+            if (!evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) {
+                var tnode = domUtils.findParent(range.startContainer, function (node) {
+                    if (node.className && domUtils.hasClass(node, "ue_t")) {
+                        return node;
+                    }
+                }, true);
+                if (tnode) {
+                    domUtils.removeClasses(tnode, ["ue_t"]);
+                }
+            }
+        }
+    });
+};

+ 30 - 0
web/js/ueditor2/_src/plugins/time.js

@@ -0,0 +1,30 @@
+///import core
+///import plugins\inserthtml.js
+///commands 日期,时间
+///commandsName  Date,Time
+///commandsTitle  日期,时间
+/**
+ * 插入日期
+ * @function
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName    date插入日期
+ * @author zhuwenxuan
+*/
+/**
+ * 插入时间
+ * @function
+ * @name baidu.editor.execCommand
+ * @param   {String}   cmdName    time插入时间
+ * @author zhuwenxuan
+*/
+UE.commands['time'] = UE.commands["date"] = {
+    execCommand : function(cmd){
+        var date = new Date;
+        this.execCommand('insertHtml',cmd == "time" ?
+            (date.getHours()+":"+ (date.getMinutes()<10 ? "0"+date.getMinutes() : date.getMinutes())+":"+(date.getSeconds()<10 ? "0"+date.getSeconds() : date.getSeconds())) :
+            (date.getFullYear()+"-"+((date.getMonth()+1)<10 ? "0"+(date.getMonth()+1) : date.getMonth()+1)+"-"+(date.getDate()<10?"0"+date.getDate():date.getDate())));
+    }
+};
+
+
+

+ 245 - 0
web/js/ueditor2/_src/plugins/undo.js

@@ -0,0 +1,245 @@
+///import core
+///commands 撤销和重做
+///commandsName  Undo,Redo
+///commandsTitle  撤销,重做
+/**
+ * @description 回退
+ * @author zhanyi
+ */
+
+UE.plugins['undo'] = function () {
+    var me = this,
+        maxUndoCount = me.options.maxUndoCount || 20,
+        maxInputCount = me.options.maxInputCount || 20,
+        fillchar = new RegExp(domUtils.fillChar + '|<\/hr>', 'gi');// ie会产生多余的</hr>
+
+
+    function compareAddr(indexA, indexB) {
+        if (indexA.length != indexB.length)
+            return 0;
+        for (var i = 0, l = indexA.length; i < l; i++) {
+            if (indexA[i] != indexB[i])
+                return 0
+        }
+        return 1;
+    }
+
+    function compareRangeAddress(rngAddrA, rngAddrB) {
+        if (rngAddrA.collapsed != rngAddrB.collapsed) {
+            return 0;
+        }
+        if (!compareAddr(rngAddrA.startAddress, rngAddrB.startAddress) || !compareAddr(rngAddrA.endAddress, rngAddrB.endAddress)) {
+            return 0;
+        }
+        return 1;
+    }
+
+    function adjustContent(cont) {
+        var specialAttr = /\b(?:href|src|name)="[^"]*?"/gi;
+        return cont.replace(specialAttr, '')
+            .replace(/([\w\-]*?)\s*=\s*(("([^"]*)")|('([^']*)')|([^\s>]+))/gi, function (a, b, c) {
+                return b.toLowerCase() + '=' + c.replace(/['"]/g, '').toLowerCase()
+            })
+            .replace(/(<[\w\-]+)|([\w\-]+>)/gi, function (a, b, c) {
+                return (b || c).toLowerCase()
+            });
+    }
+
+    function UndoManager() {
+        this.list = [];
+        this.index = 0;
+        this.hasUndo = false;
+        this.hasRedo = false;
+        this.undo = function () {
+            if (this.hasUndo) {
+                var currentScene = this.getScene(),
+                    lastScene = this.list[this.index],
+                    lastContent = adjustContent(lastScene.content),
+                    currentContent = adjustContent(currentScene.content);
+
+                if (lastContent != currentContent) {
+                    this.save();
+                }
+                if (!this.list[this.index - 1] && this.list.length == 1) {
+                    this.reset();
+                    return;
+                }
+                while (this.list[this.index].content == this.list[this.index - 1].content) {
+                    this.index--;
+                    if (this.index == 0) {
+                        return this.restore(0);
+                    }
+                }
+                this.restore(--this.index);
+            }
+        };
+        this.redo = function () {
+            if (this.hasRedo) {
+                while (this.list[this.index].content == this.list[this.index + 1].content) {
+                    this.index++;
+                    if (this.index == this.list.length - 1) {
+                        return this.restore(this.index);
+                    }
+                }
+                this.restore(++this.index);
+            }
+        };
+
+        this.restore = function () {
+            var scene = this.list[this.index];
+            //trace:873
+            //去掉展位符
+            me.document.body.innerHTML = scene.content.replace(fillchar, '');
+            //处理undo后空格不展位的问题
+            if (browser.ie) {
+                utils.each(domUtils.getElementsByTagName(me.document,'td th caption p'),function(node){
+                    if(domUtils.isEmptyNode(node)){
+                        domUtils.fillNode(me.document, node);
+                    }
+                })
+            }
+            new dom.Range(me.document).moveToAddress(scene.address).select();
+            this.update();
+            this.clearKey();
+            //不能把自己reset了
+            me.fireEvent('reset', true);
+        };
+
+        this.getScene = function (notSetCursor) {
+            var rng = me.selection.getRange(),
+                restoreAddress = rng.createAddress(),
+                rngAddress = rng.createAddress(false,true);
+
+            me.fireEvent('beforegetscene');
+            var cont = me.body.innerHTML.replace(fillchar, '');
+            browser.ie && (cont = cont.replace(/>&nbsp;</g, '><').replace(/\s*</g, '<').replace(/>\s*/g, '>'));
+            me.fireEvent('aftergetscene');
+            try{
+                !notSetCursor && rng.moveToAddress(restoreAddress).select(true);
+            }catch(e){}
+            return {
+                address:rngAddress,
+                content:cont
+            }
+        };
+        this.save = function (notCompareRange,notSetCursor) {
+            var currentScene = this.getScene(notSetCursor),
+                lastScene = this.list[this.index];
+            //内容相同位置相同不存
+            if (lastScene && lastScene.content == currentScene.content &&
+                ( notCompareRange ? 1 : compareRangeAddress(lastScene.address, currentScene.address) )
+                ) {
+                return;
+            }
+            this.list = this.list.slice(0, this.index + 1);
+            this.list.push(currentScene);
+            //如果大于最大数量了,就把最前的剔除
+            if (this.list.length > maxUndoCount) {
+                this.list.shift();
+            }
+            this.index = this.list.length - 1;
+            this.clearKey();
+            //跟新undo/redo状态
+            this.update();
+        };
+        this.update = function () {
+            this.hasRedo = !!this.list[this.index + 1];
+            this.hasUndo = !!this.list[this.index - 1];
+        };
+        this.reset = function () {
+            this.list = [];
+            this.index = 0;
+            this.hasUndo = false;
+            this.hasRedo = false;
+            this.clearKey();
+        };
+        this.clearKey = function () {
+            keycont = 0;
+            lastKeyCode = null;
+        };
+    }
+
+    me.undoManger = new UndoManager();
+    function saveScene() {
+        this.undoManger.save();
+    }
+
+    me.addListener('saveScene', function () {
+        me.undoManger.save();
+    });
+
+    me.addListener('beforeexeccommand', saveScene);
+    me.addListener('afterexeccommand', saveScene);
+
+    me.addListener('reset', function (type, exclude) {
+        if (!exclude) {
+            me.undoManger.reset();
+        }
+    });
+    me.commands['redo'] = me.commands['undo'] = {
+        execCommand:function (cmdName) {
+            me.undoManger[cmdName]();
+        },
+        queryCommandState:function (cmdName) {
+            return me.undoManger['has' + (cmdName.toLowerCase() == 'undo' ? 'Undo' : 'Redo')] ? 0 : -1;
+        },
+        notNeedUndo:1
+    };
+
+    var keys = {
+            //  /*Backspace*/ 8:1, /*Delete*/ 46:1,
+            /*Shift*/ 16:1, /*Ctrl*/ 17:1, /*Alt*/ 18:1,
+            37:1, 38:1, 39:1, 40:1,
+            13:1 /*enter*/
+        },
+        keycont = 0,
+        lastKeyCode;
+    //输入法状态下不计算字符数
+    var inputType = false;
+    me.addListener('ready', function () {
+        domUtils.on(me.body, 'compositionstart', function () {
+            inputType = true;
+        });
+        domUtils.on(me.body, 'compositionend', function () {
+            inputType = false;
+        })
+    });
+    //快捷键
+    me.addshortcutkey({
+        "Undo":"ctrl+90", //undo
+        "Redo":"ctrl+89" //redo
+
+    });
+    me.addListener('keydown', function (type, evt) {
+        var keyCode = evt.keyCode || evt.which;
+        if (!keys[keyCode] && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) {
+            if (inputType)
+                return;
+            if (me.undoManger.list.length == 0 || ((keyCode == 8 || keyCode == 46) && lastKeyCode != keyCode)) {
+
+                me.fireEvent('contentchange');
+
+                me.undoManger.save(true,true);
+                lastKeyCode = keyCode;
+                return;
+            }
+            //trace:856
+            //修正第一次输入后,回退,再输入要到keycont>maxInputCount才能在回退的问题
+            if (me.undoManger.list.length == 2 && me.undoManger.index == 0 && keycont == 0) {
+                me.undoManger.list.splice(1, 1);
+                me.undoManger.update();
+            }
+            lastKeyCode = keyCode;
+            keycont++;
+            if (keycont >= maxInputCount || me.undoManger.mousedown) {
+                if (me.selection.getRange().collapsed)
+                    me.fireEvent('contentchange');
+                me.undoManger.save(false,true);
+                me.undoManger.mousedown = false;
+            }
+        }
+    });
+    me.addListener('mousedown',function(){
+        me.undoManger.mousedown = true;
+    })
+};

+ 77 - 0
web/js/ueditor2/_src/plugins/video.js

@@ -0,0 +1,77 @@
+///import core
+///import plugins/inserthtml.js
+///commands 视频
+///commandsName InsertVideo
+///commandsTitle  插入视频
+///commandsDialog  dialogs\video
+UE.plugins['video'] = function (){
+    var me =this,
+        div;
+
+    /**
+     * 创建插入视频字符窜
+     * @param url 视频地址
+     * @param width 视频宽度
+     * @param height 视频高度
+     * @param align 视频对齐
+     * @param toEmbed 是否以flash代替显示
+     * @param addParagraph  是否需要添加P 标签
+     */
+    function creatInsertStr(url,width,height,align,toEmbed,addParagraph){
+        return  !toEmbed ?
+                (addParagraph? ('<p '+ (align && align !="none" ? ( align == "center"? ' style="text-align:center;" ':' style="float:"'+ align ) : '') + '>'): '') +
+                '<img align="'+align+'" width="'+ width +'" height="' + height + '" _url="'+url+'" class="edui-faked-video"' +
+                ' src="' + me.options.UEDITOR_HOME_URL+'themes/default/images/spacer.gif" style="background:url('+me.options.UEDITOR_HOME_URL+'themes/default/images/videologo.gif) no-repeat center center; border:1px solid gray;" />' +
+                (addParagraph?'</p>':'')
+                :
+                '<embed type="application/x-shockwave-flash" class="edui-faked-video" pluginspage="http://www.macromedia.com/go/getflashplayer"' +
+                ' src="' + url + '" width="' + width  + '" height="' + height  + '" align="' + align + '"' +
+                ( align && align !="none" ? ' style= "'+ ( align == "center"? "display:block;":" float: "+ align )  + '"' :'' ) +
+                ' wmode="transparent" play="true" loop="false" menu="false" allowscriptaccess="never" allowfullscreen="true" >';
+    }
+
+    function switchImgAndEmbed(img2embed){
+        var tmpdiv,
+            nodes =domUtils.getElementsByTagName(me.document, !img2embed ? "embed" : "img");
+        for(var i=0,node;node = nodes[i++];){
+            if(node.className!="edui-faked-video"){
+                continue;
+            }
+            tmpdiv = me.document.createElement("div");
+            //先看float在看align,浮动有的是时候是在float上定义的
+            var align = domUtils.getComputedStyle(node,'float');
+            align = align == 'none' ? (node.getAttribute('align') || '') : align;
+            tmpdiv.innerHTML = creatInsertStr(img2embed ? node.getAttribute("_url"):node.getAttribute("src"),node.width,node.height,align,img2embed);
+            node.parentNode.replaceChild(tmpdiv.firstChild,node);
+        }
+    }
+    me.addListener("beforegetcontent",function(){
+        switchImgAndEmbed(true);
+    });
+    me.addListener('aftersetcontent',function(){
+        switchImgAndEmbed(false);
+    });
+    me.addListener('aftergetcontent',function(cmdName){
+        if(cmdName == 'aftergetcontent' && me.queryCommandState('source')){
+            return;
+        }
+        switchImgAndEmbed(false);
+    });
+
+    me.commands["insertvideo"] = {
+        execCommand: function (cmd, videoObjs){
+            videoObjs = utils.isArray(videoObjs)?videoObjs:[videoObjs];
+            var html = [];
+            for(var i=0,vi,len = videoObjs.length;i<len;i++){
+                 vi = videoObjs[i];
+                 html.push(creatInsertStr( vi.url, vi.width || 420,  vi.height || 280, vi.align||"none",false,true));
+            }
+            me.execCommand("inserthtml",html.join(""));
+        },
+        queryCommandState : function(){
+            var img = me.selection.getRange().getClosedNode(),
+                flag = img && (img.className == "edui-faked-video");
+            return flag ? 1 : 0;
+        }
+    };
+};

+ 49 - 0
web/js/ueditor2/_src/plugins/webapp.js

@@ -0,0 +1,49 @@
+///import core
+///import plugins/inserthtml.js
+///commands 百度应用
+///commandsName webapp
+///commandsTitle  百度应用
+///commandsDialog  dialogs\webapp
+UE.plugins['webapp'] = function () {
+    var me = this;
+    function createInsertStr( obj, toIframe, addParagraph ) {
+        return !toIframe ?
+                (addParagraph ? '<p>' : '') + '<img title="'+obj.title+'" width="' + obj.width + '" height="' + obj.height + '"' +
+                        ' src="' + me.options.UEDITOR_HOME_URL + 'themes/default/images/spacer.gif" style="background:url(' + obj.logo+') no-repeat center center; border:1px solid gray;" class="edui-faked-webapp" _url="' + obj.url + '" />' +
+                        (addParagraph ? '</p>' : '')
+                :
+                '<iframe class="edui-faked-webapp" title="'+obj.title+'" width="' + obj.width + '" height="' + obj.height + '"  scrolling="no" frameborder="0" src="' + obj.url + '" logo_url = '+obj.logo+'></iframe>';
+    }
+
+    function switchImgAndIframe( img2frame ) {
+        var tmpdiv,
+                nodes = domUtils.getElementsByTagName( me.document, !img2frame ? "iframe" : "img" );
+        for ( var i = 0, node; node = nodes[i++]; ) {
+            if ( node.className != "edui-faked-webapp" ){
+                continue;
+            }
+            tmpdiv = me.document.createElement( "div" );
+            tmpdiv.innerHTML = createInsertStr( img2frame ? {url:node.getAttribute( "_url" ), width:node.width, height:node.height,title:node.title,logo:node.style.backgroundImage.replace("url(","").replace(")","")} : {url:node.getAttribute( "src", 2 ),title:node.title, width:node.width, height:node.height,logo:node.getAttribute("logo_url")}, img2frame ? true : false,false );
+            node.parentNode.replaceChild( tmpdiv.firstChild, node );
+        }
+    }
+
+    me.addListener( "beforegetcontent", function () {
+        switchImgAndIframe( true );
+    } );
+    me.addListener( 'aftersetcontent', function () {
+        switchImgAndIframe( false );
+    } );
+    me.addListener( 'aftergetcontent', function ( cmdName ) {
+        if ( cmdName == 'aftergetcontent' && me.queryCommandState( 'source' ) ){
+            return;
+        }
+        switchImgAndIframe( false );
+    } );
+
+    me.commands['webapp'] = {
+        execCommand:function ( cmd, obj ) {
+            me.execCommand( "inserthtml", createInsertStr( obj, false,true ) );
+        }
+    };
+};

+ 26 - 0
web/js/ueditor2/_src/plugins/wordcount.js

@@ -0,0 +1,26 @@
+///import core
+///commands 字数统计
+///commandsName  WordCount,wordCount
+///commandsTitle  字数统计
+/**
+ * Created by JetBrains WebStorm.
+ * User: taoqili
+ * Date: 11-9-7
+ * Time: 下午8:18
+ * To change this template use File | Settings | File Templates.
+ */
+
+UE.plugins['wordcount'] = function(){
+    var me = this;
+    me.addListener('contentchange',function(){
+        me.fireEvent('wordcount')
+    });
+    var timer;
+    me.addListener('keyup',function(){
+        clearTimeout(timer);
+        var me = this;
+        timer = setTimeout(function(){
+            me.fireEvent('wordcount')
+        },200)
+    });
+};

+ 33 - 0
web/js/ueditor2/_src/plugins/wordimage.js

@@ -0,0 +1,33 @@
+///import core
+///commands 本地图片引导上传
+///commandsName  WordImage
+///commandsTitle  本地图片引导上传
+///commandsDialog  dialogs\wordimage
+
+
+UE.plugins["wordimage"] = function(){
+    var me = this,
+        images;
+    me.commands['wordimage'] = {
+        execCommand : function() {
+            images = domUtils.getElementsByTagName(me.document.body,"img");
+            var urlList = [];
+            for(var i=0,ci;ci=images[i++];){
+                var url=ci.getAttribute("word_img");
+                url && urlList.push(url);
+            }
+            if(images.length){
+                this["word_img"] = urlList;
+            }
+        },
+        queryCommandState: function(){
+            images = domUtils.getElementsByTagName(me.document.body,"img");
+            for(var i=0,ci;ci =images[i++];){
+                if(ci.getAttribute("word_img")){
+                    return 1;
+                }
+            }
+            return -1;
+        }
+    };
+};

+ 85 - 0
web/js/ueditor2/_src/ui/autotypesetbutton.js

@@ -0,0 +1,85 @@
+///import core
+///import uicore
+///import ui/popup.js
+///import ui/autotypesetpicker.js
+///import ui/splitbutton.js
+(function (){
+    var utils = baidu.editor.utils,
+        Popup = baidu.editor.ui.Popup,
+        AutoTypeSetPicker = baidu.editor.ui.AutoTypeSetPicker,
+        SplitButton = baidu.editor.ui.SplitButton,
+        AutoTypeSetButton = baidu.editor.ui.AutoTypeSetButton = function (options){
+            this.initOptions(options);
+            this.initAutoTypeSetButton();
+        };
+    function getPara(me){
+        var opt = me.editor.options.autotypeset,
+            cont = me.getDom(),
+            ipts = domUtils.getElementsByTagName(cont,"input");
+        for(var i=ipts.length-1,ipt;ipt=ipts[i--];){
+            if(ipt.getAttribute("type")=="checkbox"){
+                var attrName = ipt.getAttribute("name");
+                opt[attrName] && delete opt[attrName];
+                if(ipt.checked){
+                    var attrValue = document.getElementById(attrName+"Value");
+                    if(attrValue){
+                        if(/input/ig.test(attrValue.tagName)){
+                            opt[attrName] = attrValue.value;
+                        }else{
+                            var iptChilds = attrValue.getElementsByTagName("input");
+                            for(var j=iptChilds.length-1,iptchild;iptchild=iptChilds[j--];){
+                                if(iptchild.checked){
+                                    opt[attrName] = iptchild.value;
+                                    break;
+                                }
+                            }
+                        }
+                    }else{
+                        opt[attrName] = true;
+                    }
+                }
+            }
+        }
+        var selects = domUtils.getElementsByTagName(cont,"select");
+        for(var i=0,si;si=selects[i++];){
+            var attr = si.getAttribute('name');
+            opt[attr] = opt[attr] ? si.value : '';
+        }
+        me.editor.options.autotypeset = opt;
+    }
+    AutoTypeSetButton.prototype = {
+        initAutoTypeSetButton: function (){
+            var me = this;
+            this.popup = new Popup({
+                //传入配置参数
+                content: new AutoTypeSetPicker({editor:me.editor}),
+                'editor':me.editor,
+                hide : function(){
+
+                    if (!this._hidden && this.getDom()) {
+                        getPara(this);
+                        this.getDom().style.display = 'none';
+                        this._hidden = true;
+                        this.fireEvent('hide');
+                    }
+                }
+            });
+            var flag = 0;
+            this.popup.addListener('postRenderAfter',function(){
+                var popupUI = this;
+                if(flag)return;
+                var cont = this.getDom(),
+                    btn = cont.getElementsByTagName('button')[0];
+                btn.onclick = function(){
+                    getPara(popupUI);
+                    me.editor.execCommand('autotypeset');
+                    popupUI.hide()
+                };
+                flag = 1;
+            });
+            this.initSplitButton();
+        }
+    };
+    utils.inherits(AutoTypeSetButton, SplitButton);
+
+})();

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 46 - 0
web/js/ueditor2/_src/ui/autotypesetpicker.js


+ 46 - 0
web/js/ueditor2/_src/ui/button.js

@@ -0,0 +1,46 @@
+///import core
+///import uicore
+///import ui/stateful.js
+(function (){
+    var utils = baidu.editor.utils,
+        UIBase = baidu.editor.ui.UIBase,
+        Stateful = baidu.editor.ui.Stateful,
+        Button = baidu.editor.ui.Button = function (options){
+            this.initOptions(options);
+            this.initButton();
+        };
+    Button.prototype = {
+        uiName: 'button',
+        label: '',
+        title: '',
+        showIcon: true,
+        showText: true,
+        initButton: function (){
+            this.initUIBase();
+            this.Stateful_init();
+        },
+        getHtmlTpl: function (){
+            return '<div id="##" class="edui-box %%">' +
+                '<div id="##_state" stateful>' +
+                 '<div class="%%-wrap"><div id="##_body" unselectable="on" ' + (this.title ? 'title="' + this.title + '"' : '') +
+                 ' class="%%-body" onmousedown="return false;" onclick="return $$._onClick();">' +
+                  (this.showIcon ? '<div class="edui-box edui-icon"></div>' : '') +
+                  (this.showText ? '<div class="edui-box edui-label">' + this.label + '</div>' : '') +
+                 '</div>' +
+                '</div>' +
+                '</div></div>';
+        },
+        postRender: function (){
+            this.Stateful_postRender();
+            this.setDisabled(this.disabled)
+        },
+        _onClick: function (){
+            if (!this.isDisabled()) {
+                this.fireEvent('click');
+            }
+        }
+    };
+    utils.inherits(Button, UIBase);
+    utils.extend(Button.prototype, Stateful);
+
+})();

+ 55 - 0
web/js/ueditor2/_src/ui/cellalignpicker.js

@@ -0,0 +1,55 @@
+///import core
+///import uicore
+(function () {
+    var utils = baidu.editor.utils,
+        Popup = baidu.editor.ui.Popup,
+        Stateful = baidu.editor.ui.Stateful,
+        UIBase = baidu.editor.ui.UIBase;
+
+    var CellAlignPicker = baidu.editor.ui.CellAlignPicker = function (options) {
+        this.initOptions(options);
+        this.initCellAlignPicker();
+    };
+    CellAlignPicker.prototype = {
+        initCellAlignPicker:function () {
+            this.initUIBase();
+            this.Stateful_init();
+        },
+        getHtmlTpl:function () {
+            return '<div id="##" class="edui-cellalignpicker %%">' +
+                '<div class="edui-cellalignpicker-body">' +
+                '<table onclick="$$._onClick(event);">' +
+                '<tr><td index="0" stateful><div class="edui-icon edui-left"></div></td>' +
+                '<td index="1" stateful><div class="edui-icon edui-center"></div></td>' +
+                '<td index="2" stateful><div class="edui-icon edui-right"></div></td>' +
+                '</tr>' +
+                '<tr><td index="3" stateful><div class="edui-icon edui-left"></div></td>' +
+                '<td index="4" stateful><div class="edui-icon edui-center"></div></td>' +
+                '<td index="5" stateful><div class="edui-icon edui-right"></div></td>' +
+                '</tr>' +
+                '<tr><td index="6" stateful><div class="edui-icon edui-left"></div></td>' +
+                '<td index="7" stateful><div class="edui-icon edui-center"></div></td>' +
+                '<td index="8" stateful><div class="edui-icon edui-right"></div></td>' +
+                '</tr>' +
+                '</table>' +
+                '</div>' +
+                '</div>';
+        },
+        getStateDom: function (){
+            return this.target;
+        },
+        _onClick: function (evt){
+            var target= evt.target || evt.srcElement;
+            if(/icon/.test(target.className)){
+                this.items[target.parentNode.getAttribute("index")].onclick();
+                Popup.postHide(evt);
+            }
+        },
+        _UIBase_render:UIBase.prototype.render
+    };
+    utils.inherits(CellAlignPicker, UIBase);
+    utils.extend(CellAlignPicker.prototype, Stateful,true);
+})();
+
+
+

+ 60 - 0
web/js/ueditor2/_src/ui/colorbutton.js

@@ -0,0 +1,60 @@
+///import core
+///import uicore
+///import ui/colorpicker.js
+///import ui/popup.js
+///import ui/splitbutton.js
+(function (){
+    var utils = baidu.editor.utils,
+        uiUtils = baidu.editor.ui.uiUtils,
+        ColorPicker = baidu.editor.ui.ColorPicker,
+        Popup = baidu.editor.ui.Popup,
+        SplitButton = baidu.editor.ui.SplitButton,
+        ColorButton = baidu.editor.ui.ColorButton = function (options){
+            this.initOptions(options);
+            this.initColorButton();
+        };
+    ColorButton.prototype = {
+        initColorButton: function (){
+            var me = this;
+            this.popup = new Popup({
+                content: new ColorPicker({
+                    noColorText: me.editor.getLang("clearColor"),
+                    editor:me.editor,
+                    onpickcolor: function (t, color){
+                        me._onPickColor(color);
+                    },
+                    onpicknocolor: function (t, color){
+                        me._onPickNoColor(color);
+                    }
+                }),
+                editor:me.editor
+            });
+            this.initSplitButton();
+        },
+        _SplitButton_postRender: SplitButton.prototype.postRender,
+        postRender: function (){
+            this._SplitButton_postRender();
+            this.getDom('button_body').appendChild(
+                uiUtils.createElementByHtml('<div id="' + this.id + '_colorlump" class="edui-colorlump"></div>')
+                );
+            this.getDom().className += ' edui-colorbutton';
+        },
+        setColor: function (color){
+            this.getDom('colorlump').style.backgroundColor = color;
+            this.color = color;
+        },
+        _onPickColor: function (color){
+            if (this.fireEvent('pickcolor', color) !== false) {
+                this.setColor(color);
+                this.popup.hide();
+            }
+        },
+        _onPickNoColor: function (color){
+            if (this.fireEvent('picknocolor') !== false) {
+                this.popup.hide();
+            }
+        }
+    };
+    utils.inherits(ColorButton, SplitButton);
+
+})();

+ 74 - 0
web/js/ueditor2/_src/ui/colorpicker.js

@@ -0,0 +1,74 @@
+///import core
+///import uicore
+(function (){
+    var utils = baidu.editor.utils,
+        UIBase = baidu.editor.ui.UIBase,
+        ColorPicker = baidu.editor.ui.ColorPicker = function (options){
+            this.initOptions(options);
+            this.noColorText = this.noColorText || this.editor.getLang("clearColor");
+            this.initUIBase();
+        };
+
+    ColorPicker.prototype = {
+        getHtmlTpl: function (){
+            return genColorPicker(this.noColorText,this.editor);
+        },
+        _onTableClick: function (evt){
+            var tgt = evt.target || evt.srcElement;
+            var color = tgt.getAttribute('data-color');
+            if (color) {
+                this.fireEvent('pickcolor', color);
+            }
+        },
+        _onTableOver: function (evt){
+            var tgt = evt.target || evt.srcElement;
+            var color = tgt.getAttribute('data-color');
+            if (color) {
+                this.getDom('preview').style.backgroundColor = color;
+            }
+        },
+        _onTableOut: function (){
+            this.getDom('preview').style.backgroundColor = '';
+        },
+        _onPickNoColor: function (){
+            this.fireEvent('picknocolor');
+        }
+    };
+    utils.inherits(ColorPicker, UIBase);
+
+    var COLORS = (
+            'ffffff,000000,eeece1,1f497d,4f81bd,c0504d,9bbb59,8064a2,4bacc6,f79646,' +
+            'f2f2f2,7f7f7f,ddd9c3,c6d9f0,dbe5f1,f2dcdb,ebf1dd,e5e0ec,dbeef3,fdeada,' +
+            'd8d8d8,595959,c4bd97,8db3e2,b8cce4,e5b9b7,d7e3bc,ccc1d9,b7dde8,fbd5b5,' +
+            'bfbfbf,3f3f3f,938953,548dd4,95b3d7,d99694,c3d69b,b2a2c7,92cddc,fac08f,' +
+            'a5a5a5,262626,494429,17365d,366092,953734,76923c,5f497a,31859b,e36c09,' +
+            '7f7f7f,0c0c0c,1d1b10,0f243e,244061,632423,4f6128,3f3151,205867,974806,' +
+            'c00000,ff0000,ffc000,ffff00,92d050,00b050,00b0f0,0070c0,002060,7030a0,').split(',');
+
+    function genColorPicker(noColorText,editor){
+        var html = '<div id="##" class="edui-colorpicker %%">' +
+            '<div class="edui-colorpicker-topbar edui-clearfix">' +
+             '<div unselectable="on" id="##_preview" class="edui-colorpicker-preview"></div>' +
+             '<div unselectable="on" class="edui-colorpicker-nocolor" onclick="$$._onPickNoColor(event, this);">'+ noColorText +'</div>' +
+            '</div>' +
+            '<table  class="edui-box" style="border-collapse: collapse;" onmouseover="$$._onTableOver(event, this);" onmouseout="$$._onTableOut(event, this);" onclick="return $$._onTableClick(event, this);" cellspacing="0" cellpadding="0">' +
+            '<tr style="border-bottom: 1px solid #ddd;font-size: 13px;line-height: 25px;color:#39C;padding-top: 2px"><td colspan="10">'+editor.getLang("themeColor")+'</td> </tr>'+
+            '<tr class="edui-colorpicker-tablefirstrow" >';
+        for (var i=0; i<COLORS.length; i++) {
+            if (i && i%10 === 0) {
+                html += '</tr>'+(i==60?'<tr style="border-bottom: 1px solid #ddd;font-size: 13px;line-height: 25px;color:#39C;"><td colspan="10">'+editor.getLang("standardColor")+'</td></tr>':'')+'<tr'+(i==60?' class="edui-colorpicker-tablefirstrow"':'')+'>';
+            }
+            html += i<70 ? '<td style="padding: 0 2px;"><a hidefocus title="'+COLORS[i]+'" onclick="return false;" href="javascript:" unselectable="on" class="edui-box edui-colorpicker-colorcell"' +
+                        ' data-color="#'+ COLORS[i] +'"'+
+                        ' style="background-color:#'+ COLORS[i] +';border:solid #ccc;'+
+                        (i<10 || i>=60?'border-width:1px;':
+                         i>=10&&i<20?'border-width:1px 1px 0 1px;':
+
+                        'border-width:0 1px 0 1px;')+
+                        '"' +
+                    '></a></td>':'';
+        }
+        html += '</tr></table></div>';
+        return html;
+    }
+})();

+ 90 - 0
web/js/ueditor2/_src/ui/combox.js

@@ -0,0 +1,90 @@
+///import core
+///import uicore
+///import ui/menu.js
+///import ui/splitbutton.js
+(function (){
+    // todo: menu和item提成通用list
+    var utils = baidu.editor.utils,
+        uiUtils = baidu.editor.ui.uiUtils,
+        Menu = baidu.editor.ui.Menu,
+        SplitButton = baidu.editor.ui.SplitButton,
+        Combox = baidu.editor.ui.Combox = function (options){
+            this.initOptions(options);
+            this.initCombox();
+        };
+    Combox.prototype = {
+        uiName: 'combox',
+        initCombox: function (){
+            var me = this;
+            this.items = this.items || [];
+            for (var i=0; i<this.items.length; i++) {
+                var item = this.items[i];
+                item.uiName = 'listitem';
+                item.index = i;
+                item.onclick = function (){
+                    me.selectByIndex(this.index);
+                };
+            }
+            this.popup = new Menu({
+                items: this.items,
+                uiName: 'list',
+                editor:this.editor
+            });
+            this.initSplitButton();
+        },
+        _SplitButton_postRender: SplitButton.prototype.postRender,
+        postRender: function (){
+            this._SplitButton_postRender();
+            this.setLabel(this.label || '');
+            this.setValue(this.initValue || '');
+        },
+        showPopup: function (){
+            var rect = uiUtils.getClientRect(this.getDom());
+            rect.top += 1;
+            rect.bottom -= 1;
+            rect.height -= 2;
+            this.popup.showAnchorRect(rect);
+        },
+        getValue: function (){
+            return this.value;
+        },
+        setValue: function (value){
+            var index = this.indexByValue(value);
+            if (index != -1) {
+                this.selectedIndex = index;
+                this.setLabel(this.items[index].label);
+                this.value = this.items[index].value;
+            } else {
+                this.selectedIndex = -1;
+                this.setLabel(this.getLabelForUnknowValue(value));
+                this.value = value;
+            }
+        },
+        setLabel: function (label){
+            this.getDom('button_body').innerHTML = label;
+            this.label = label;
+        },
+        getLabelForUnknowValue: function (value){
+            return value;
+        },
+        indexByValue: function (value){
+            for (var i=0; i<this.items.length; i++) {
+                if (value == this.items[i].value) {
+                    return i;
+                }
+            }
+            return -1;
+        },
+        getItem: function (index){
+            return this.items[index];
+        },
+        selectByIndex: function (index){
+            if (index < this.items.length && this.fireEvent('select', index) !== false) {
+                this.selectedIndex = index;
+                this.value = this.items[index].value;
+                this.setLabel(this.items[index].label);
+            }
+        }
+    };
+    utils.inherits(Combox, SplitButton);
+})();

+ 0 - 0
web/js/ueditor2/_src/ui/dialog.js


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác