keystrokes.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * 处理特殊键的兼容性问题
  3. */
  4. UE.plugins['keystrokes'] = function() {
  5. var me = this;
  6. me.addListener('keydown', function(type, evt) {
  7. var keyCode = evt.keyCode || evt.which,
  8. rng = me.selection.getRange();
  9. //处理全选的情况
  10. if(!rng.collapsed && !(evt.ctrlKey || evt.metaKey || evt.shiftKey || evt.altKey || keyCode == 9 )){
  11. var tmpNode = rng.startContainer;
  12. if(domUtils.isFillChar(tmpNode)){
  13. rng.setStartBefore(tmpNode)
  14. }
  15. tmpNode = rng.endContainer;
  16. if(domUtils.isFillChar(tmpNode)){
  17. rng.setEndAfter(tmpNode)
  18. }
  19. rng.txtToElmBoundary();
  20. //结束边界可能放到了br的前边,要把br包含进来
  21. // x[xxx]<br/>
  22. if(rng.endContainer && rng.endContainer.nodeType == 1){
  23. tmpNode = rng.endContainer.childNodes[rng.endOffset];
  24. if(tmpNode && domUtils.isBr(tmpNode)){
  25. rng.setEndAfter(tmpNode);
  26. }
  27. }
  28. if(rng.startOffset == 0){
  29. tmpNode = rng.startContainer;
  30. if(domUtils.isBoundaryNode(tmpNode,'firstChild') ){
  31. tmpNode = rng.endContainer;
  32. if(rng.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode,'lastChild')){
  33. me.fireEvent('saveScene');
  34. me.body.innerHTML = '<p>'+(browser.ie ? '' : '<br/>')+'</p>';
  35. rng.setStart(me.body.firstChild,0).setCursor(false,true);
  36. browser.ie && me._selectionChange();
  37. domUtils.preventDefault(evt);
  38. return;
  39. }
  40. }
  41. }
  42. }
  43. //处理backspace/del
  44. if (keyCode == 8) {//|| keyCode == 46
  45. var start,end;
  46. //避免按两次删除才能生效的问题
  47. if(rng.inFillChar()){
  48. start = rng.startContainer;
  49. rng.setStartBefore(start).shrinkBoundary(true).collapse(true);
  50. if(domUtils.isFillChar(start)){
  51. domUtils.remove(start)
  52. }else{
  53. start.nodeValue = start.nodeValue.replace(new RegExp('^' + domUtils.fillChar ),'');
  54. }
  55. }
  56. //解决选中control元素不能删除的问题
  57. if (start = rng.getClosedNode()) {
  58. me.fireEvent('saveScene');
  59. rng.setStartBefore(start);
  60. domUtils.remove(start);
  61. rng.setCursor();
  62. me.fireEvent('saveScene');
  63. domUtils.preventDefault(evt);
  64. return;
  65. }
  66. //阻止在table上的删除
  67. if (!browser.ie) {
  68. start = domUtils.findParentByTagName(rng.startContainer, 'table', true);
  69. end = domUtils.findParentByTagName(rng.endContainer, 'table', true);
  70. if (start && !end || !start && end || start !== end) {
  71. evt.preventDefault();
  72. return;
  73. }
  74. }
  75. }
  76. //处理tab键的逻辑
  77. if (keyCode == 9) {
  78. //不处理以下标签
  79. var excludeTagNameForTabKey = {
  80. 'ol' : 1,
  81. 'ul' : 1,
  82. 'table':1
  83. };
  84. //处理组件里的tab按下事件
  85. if(me.fireEvent('tabkeydown')){
  86. domUtils.preventDefault(evt);
  87. return;
  88. }
  89. range = me.selection.getRange();
  90. me.fireEvent('saveScene');
  91. for (var i = 0,txt = '',tabSize = me.options.tabSize|| 4,tabNode = me.options.tabNode || '&nbsp;'; i < tabSize; i++) {
  92. txt += tabNode;
  93. }
  94. var span = me.document.createElement('span');
  95. span.innerHTML = txt + domUtils.fillChar;
  96. if (range.collapsed) {
  97. range.insertNode(span.cloneNode(true).firstChild).setCursor(true);
  98. } else {
  99. //普通的情况
  100. start = domUtils.findParent(range.startContainer, filterFn);
  101. end = domUtils.findParent(range.endContainer, filterFn);
  102. if (start && end && start === end) {
  103. range.deleteContents();
  104. range.insertNode(span.cloneNode(true).firstChild).setCursor(true);
  105. } else {
  106. var bookmark = range.createBookmark(),
  107. filterFn = function(node) {
  108. return domUtils.isBlockElm(node) && !excludeTagNameForTabKey[node.tagName.toLowerCase()]
  109. };
  110. range.enlarge(true);
  111. var bookmark2 = range.createBookmark(),
  112. current = domUtils.getNextDomNode(bookmark2.start, false, filterFn);
  113. while (current && !(domUtils.getPosition(current, bookmark2.end) & domUtils.POSITION_FOLLOWING)) {
  114. current.insertBefore(span.cloneNode(true).firstChild, current.firstChild);
  115. current = domUtils.getNextDomNode(current, false, filterFn);
  116. }
  117. range.moveToBookmark(bookmark2).moveToBookmark(bookmark).select();
  118. }
  119. }
  120. domUtils.preventDefault(evt)
  121. }
  122. //trace:1634
  123. //ff的del键在容器空的时候,也会删除
  124. if(browser.gecko && keyCode == 46){
  125. range = me.selection.getRange();
  126. if(range.collapsed){
  127. start = range.startContainer;
  128. if(domUtils.isEmptyBlock(start)){
  129. var parent = start.parentNode;
  130. while(domUtils.getChildCount(parent) == 1 && !domUtils.isBody(parent)){
  131. start = parent;
  132. parent = parent.parentNode;
  133. }
  134. if(start === parent.lastChild)
  135. evt.preventDefault();
  136. return;
  137. }
  138. }
  139. }
  140. });
  141. me.addListener('keyup', function(type, evt) {
  142. var keyCode = evt.keyCode || evt.which,
  143. rng;
  144. if(keyCode == 8){
  145. rng = me.selection.getRange();
  146. //处理当删除到body时,要重新给p标签展位
  147. if(rng.collapsed && domUtils.isBody(rng.startContainer)){
  148. var tmpNode = domUtils.createElement(me.document,'p',{
  149. 'innerHTML' : browser.ie ? domUtils.fillChar : '<br/>'
  150. });
  151. rng.insertNode(tmpNode).setStart(tmpNode,0).setCursor(false,true);
  152. }
  153. // //chrome下如果删除了inline标签,浏览器会有记忆,在输入文字还是会套上刚才删除的标签,所以这里再选一次就不会了
  154. if(browser.chrome && rng.collapsed && rng.startContainer.nodeType == 1 && domUtils.isEmptyBlock(rng.startContainer)){
  155. rng.select(true);
  156. }
  157. }
  158. })
  159. };