PageRenderTime 22ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/AKDOA28/ZX.WebApp/ExtendPage/editor/_src/plugins/paste.js

#
JavaScript | 284 lines | 236 code | 21 blank | 27 comment | 67 complexity | 813b0bf9e3287fbbd679c7df1faf9d43 MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-3.0, Apache-2.0, GPL-2.0, BSD-3-Clause, LGPL-2.0, MIT, GPL-3.0
  1. ///import core
  2. ///import plugins/inserthtml.js
  3. ///import plugins/undo.js
  4. ///import plugins/serialize.js
  5. ///commands 粘贴
  6. ///commandsName PastePlain
  7. ///commandsTitle 纯文本粘贴模式
  8. /*
  9. ** @description 粘贴
  10. * @author zhanyi
  11. */
  12. UE.plugins['paste'] = function () {
  13. function getClipboardData(callback) {
  14. var doc = this.document;
  15. if (doc.getElementById('baidu_pastebin')) {
  16. return;
  17. }
  18. var range = this.selection.getRange(),
  19. bk = range.createBookmark(),
  20. //创建剪贴的容器div
  21. pastebin = doc.createElement('div');
  22. pastebin.id = 'baidu_pastebin';
  23. // Safari 要求div必须有内容,才能粘贴内容进来
  24. browser.webkit && pastebin.appendChild(doc.createTextNode(domUtils.fillChar + domUtils.fillChar));
  25. doc.body.appendChild(pastebin);
  26. //trace:717 隐藏的span不能得到top
  27. //bk.start.innerHTML = ' ';
  28. bk.start.style.display = '';
  29. pastebin.style.cssText = "position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:" +
  30. //要在现在光标平行的位置加入,否则会出现跳动的问题
  31. domUtils.getXY(bk.start).y + 'px';
  32. range.selectNodeContents(pastebin).select(true);
  33. setTimeout(function () {
  34. if (browser.webkit) {
  35. for (var i = 0, pastebins = doc.querySelectorAll('#baidu_pastebin'), pi; pi = pastebins[i++];) {
  36. if (domUtils.isEmptyNode(pi)) {
  37. domUtils.remove(pi);
  38. } else {
  39. pastebin = pi;
  40. break;
  41. }
  42. }
  43. }
  44. try {
  45. pastebin.parentNode.removeChild(pastebin);
  46. } catch (e) {
  47. }
  48. range.moveToBookmark(bk).select(true);
  49. callback(pastebin);
  50. }, 0);
  51. }
  52. var me = this;
  53. var txtContent, htmlContent, address;
  54. function filter(div) {
  55. var html;
  56. if (div.firstChild) {
  57. //去掉cut中添加的边界值
  58. var nodes = domUtils.getElementsByTagName(div, 'span');
  59. for (var i = 0, ni; ni = nodes[i++];) {
  60. if (ni.id == '_baidu_cut_start' || ni.id == '_baidu_cut_end') {
  61. domUtils.remove(ni);
  62. }
  63. }
  64. if (browser.webkit) {
  65. var brs = div.querySelectorAll('div br');
  66. for (var i = 0, bi; bi = brs[i++];) {
  67. var pN = bi.parentNode;
  68. if (pN.tagName == 'DIV' && pN.childNodes.length == 1) {
  69. pN.innerHTML = '<p><br/></p>';
  70. domUtils.remove(pN);
  71. }
  72. }
  73. var divs = div.querySelectorAll('#baidu_pastebin');
  74. for (var i = 0, di; di = divs[i++];) {
  75. var tmpP = me.document.createElement('p');
  76. di.parentNode.insertBefore(tmpP, di);
  77. while (di.firstChild) {
  78. tmpP.appendChild(di.firstChild);
  79. }
  80. domUtils.remove(di);
  81. }
  82. var metas = div.querySelectorAll('meta');
  83. for (var i = 0, ci; ci = metas[i++];) {
  84. domUtils.remove(ci);
  85. }
  86. var brs = div.querySelectorAll('br');
  87. for (i = 0; ci = brs[i++];) {
  88. if (/^apple-/i.test(ci.className)) {
  89. domUtils.remove(ci);
  90. }
  91. }
  92. }
  93. if (browser.gecko) {
  94. var dirtyNodes = div.querySelectorAll('[_moz_dirty]');
  95. for (i = 0; ci = dirtyNodes[i++];) {
  96. ci.removeAttribute('_moz_dirty');
  97. }
  98. }
  99. if (!browser.ie) {
  100. var spans = div.querySelectorAll('span.Apple-style-span');
  101. for (var i = 0, ci; ci = spans[i++];) {
  102. domUtils.remove(ci, true);
  103. }
  104. }
  105. //ie下使用innerHTML会产生多余的\r\n字符,也会产生&nbsp;这里过滤掉
  106. html = div.innerHTML;//.replace(/>(?:(\s|&nbsp;)*?)</g,'><');
  107. //过滤word粘贴过来的冗余属性
  108. html = UE.filterWord(html);
  109. //取消了忽略空白的第二个参数,粘贴过来的有些是有空白的,会被套上相关的标签
  110. var root = UE.htmlparser(html);
  111. //如果给了过滤规则就先进行过滤
  112. if (me.options.filterRules) {
  113. UE.filterNode(root, me.options.filterRules);
  114. }
  115. //执行默认的处理
  116. me.filterInputRule(root);
  117. //针对chrome的处理
  118. if (browser.webkit) {
  119. var br = root.lastChild();
  120. if (br && br.type == 'element' && br.tagName == 'br') {
  121. root.removeChild(br)
  122. }
  123. utils.each(me.body.querySelectorAll('div'), function (node) {
  124. if (domUtils.isEmptyBlock(node)) {
  125. domUtils.remove(node,true)
  126. }
  127. })
  128. }
  129. html = {'html': root.toHtml()};
  130. me.fireEvent('beforepaste', html, root);
  131. //抢了默认的粘贴,那后边的内容就不执行了,比如表格粘贴
  132. if(!html.html){
  133. return;
  134. }
  135. root = UE.htmlparser(html.html,true);
  136. //如果开启了纯文本模式
  137. if (me.queryCommandState('pasteplain') === 1) {
  138. me.execCommand('insertHtml', UE.filterNode(root, me.options.filterTxtRules).toHtml(), true);
  139. } else {
  140. //文本模式
  141. UE.filterNode(root, me.options.filterTxtRules);
  142. txtContent = root.toHtml();
  143. //完全模式
  144. htmlContent = html.html;
  145. address = me.selection.getRange().createAddress(true);
  146. me.execCommand('insertHtml', htmlContent, true);
  147. }
  148. me.fireEvent("afterpaste", html);
  149. }
  150. }
  151. me.addListener('pasteTransfer', function (cmd, plainType) {
  152. if (address && txtContent && htmlContent && txtContent != htmlContent) {
  153. var range = me.selection.getRange();
  154. range.moveToAddress(address, true);
  155. if (!range.collapsed) {
  156. while (!domUtils.isBody(range.startContainer)
  157. ) {
  158. var start = range.startContainer;
  159. if(start.nodeType == 1){
  160. start = start.childNodes[range.startOffset];
  161. if(!start){
  162. range.setStartBefore(range.startContainer);
  163. continue;
  164. }
  165. var pre = start.previousSibling;
  166. if(pre && pre.nodeType == 3 && new RegExp('^[\n\r\t '+domUtils.fillChar+']*$').test(pre.nodeValue)){
  167. range.setStartBefore(pre)
  168. }
  169. }
  170. if(range.startOffset == 0){
  171. range.setStartBefore(range.startContainer);
  172. }else{
  173. break;
  174. }
  175. }
  176. while (!domUtils.isBody(range.endContainer)
  177. ) {
  178. var end = range.endContainer;
  179. if(end.nodeType == 1){
  180. end = end.childNodes[range.endOffset];
  181. if(!end){
  182. range.setEndAfter(range.endContainer);
  183. continue;
  184. }
  185. var next = end.nextSibling;
  186. if(next && next.nodeType == 3 && new RegExp('^[\n\r\t'+domUtils.fillChar+']*$').test(next.nodeValue)){
  187. range.setEndAfter(next)
  188. }
  189. }
  190. if(range.endOffset == range.endContainer[range.endContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length){
  191. range.setEndAfter(range.endContainer);
  192. }else{
  193. break;
  194. }
  195. }
  196. }
  197. range.deleteContents();
  198. range.select(true);
  199. me.__hasEnterExecCommand = true;
  200. var html = htmlContent;
  201. if (plainType === 2) {
  202. html = html.replace(/<(\/?)([\w\-]+)([^>]*)>/gi, function (a, b, tagName, attrs) {
  203. tagName = tagName.toLowerCase();
  204. if ({img: 1}[tagName]) {
  205. return a;
  206. }
  207. attrs = attrs.replace(/([\w\-]*?)\s*=\s*(("([^"]*)")|('([^']*)')|([^\s>]+))/gi, function (str, atr, val) {
  208. if ({
  209. 'src': 1,
  210. 'href': 1,
  211. 'name': 1
  212. }[atr.toLowerCase()]) {
  213. return atr + '=' + val + ' '
  214. }
  215. return ''
  216. });
  217. if ({
  218. 'span': 1,
  219. 'div': 1
  220. }[tagName]) {
  221. return ''
  222. } else {
  223. return '<' + b + tagName + ' ' + utils.trim(attrs) + '>'
  224. }
  225. });
  226. } else if (plainType) {
  227. html = txtContent;
  228. }
  229. me.execCommand('inserthtml', html, true);
  230. me.__hasEnterExecCommand = false;
  231. var rng = me.selection.getRange();
  232. while (!domUtils.isBody(rng.startContainer) && !rng.startOffset &&
  233. rng.startContainer[rng.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length
  234. ) {
  235. rng.setStartBefore(rng.startContainer);
  236. }
  237. var tmpAddress = rng.createAddress(true);
  238. address.endAddress = tmpAddress.startAddress;
  239. }
  240. });
  241. me.addListener('ready', function () {
  242. domUtils.on(me.body, 'cut', function () {
  243. var range = me.selection.getRange();
  244. if (!range.collapsed && me.undoManger) {
  245. me.undoManger.save();
  246. }
  247. });
  248. //ie下beforepaste在点击右键时也会触发,所以用监控键盘才处理
  249. domUtils.on(me.body, browser.ie || browser.opera ? 'keydown' : 'paste', function (e) {
  250. if ((browser.ie || browser.opera) && ((!e.ctrlKey && !e.metaKey) || e.keyCode != '86')) {
  251. return;
  252. }
  253. getClipboardData.call(me, function (div) {
  254. filter(div);
  255. });
  256. });
  257. });
  258. };