removeformat.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /**
  2. * 清除格式
  3. * @file
  4. * @since 1.2.6.1
  5. */
  6. /**
  7. * 清除文字样式
  8. * @command removeformat
  9. * @method execCommand
  10. * @param { String } cmd 命令字符串
  11. * @param {String} tags 以逗号隔开的标签。如:strong
  12. * @param {String} style 样式如:color
  13. * @param {String} attrs 属性如:width
  14. * @example
  15. * ```javascript
  16. * editor.execCommand( 'removeformat', 'strong','color','width' );
  17. * ```
  18. */
  19. UE.plugins["removeformat"] = function() {
  20. var me = this;
  21. me.setOpt({
  22. removeFormatTags:
  23. "b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var",
  24. removeFormatAttributes: "class,style,lang,width,height,align,hspace,valign"
  25. });
  26. me.commands["removeformat"] = {
  27. execCommand: function(cmdName, tags, style, attrs, notIncludeA) {
  28. var tagReg = new RegExp(
  29. "^(?:" +
  30. (tags || this.options.removeFormatTags).replace(/,/g, "|") +
  31. ")$",
  32. "i"
  33. ),
  34. removeFormatAttributes = style
  35. ? []
  36. : (attrs || this.options.removeFormatAttributes).split(","),
  37. range = new dom.Range(this.document),
  38. bookmark,
  39. node,
  40. parent,
  41. filter = function(node) {
  42. return node.nodeType == 1;
  43. };
  44. function isRedundantSpan(node) {
  45. if (node.nodeType == 3 || node.tagName.toLowerCase() != "span") {
  46. return 0;
  47. }
  48. if (browser.ie) {
  49. //ie 下判断实效,所以只能简单用style来判断
  50. //return node.style.cssText == '' ? 1 : 0;
  51. var attrs = node.attributes;
  52. if (attrs.length) {
  53. for (var i = 0, l = attrs.length; i < l; i++) {
  54. if (attrs[i].specified) {
  55. return 0;
  56. }
  57. }
  58. return 1;
  59. }
  60. }
  61. return !node.attributes.length;
  62. }
  63. function doRemove(range) {
  64. var bookmark1 = range.createBookmark();
  65. if (range.collapsed) {
  66. range.enlarge(true);
  67. }
  68. //不能把a标签切了
  69. if (!notIncludeA) {
  70. var aNode = domUtils.findParentByTagName(
  71. range.startContainer,
  72. "a",
  73. true
  74. );
  75. if (aNode) {
  76. range.setStartBefore(aNode);
  77. }
  78. aNode = domUtils.findParentByTagName(range.endContainer, "a", true);
  79. if (aNode) {
  80. range.setEndAfter(aNode);
  81. }
  82. }
  83. bookmark = range.createBookmark();
  84. node = bookmark.start;
  85. //切开始
  86. while ((parent = node.parentNode) && !domUtils.isBlockElm(parent)) {
  87. domUtils.breakParent(node, parent);
  88. domUtils.clearEmptySibling(node);
  89. }
  90. if (bookmark.end) {
  91. //切结束
  92. node = bookmark.end;
  93. while ((parent = node.parentNode) && !domUtils.isBlockElm(parent)) {
  94. domUtils.breakParent(node, parent);
  95. domUtils.clearEmptySibling(node);
  96. }
  97. //开始去除样式
  98. var current = domUtils.getNextDomNode(bookmark.start, false, filter),
  99. next;
  100. while (current) {
  101. if (current == bookmark.end) {
  102. break;
  103. }
  104. next = domUtils.getNextDomNode(current, true, filter);
  105. if (
  106. !dtd.$empty[current.tagName.toLowerCase()] &&
  107. !domUtils.isBookmarkNode(current)
  108. ) {
  109. if (tagReg.test(current.tagName)) {
  110. if (style) {
  111. domUtils.removeStyle(current, style);
  112. if (isRedundantSpan(current) && style != "text-decoration") {
  113. domUtils.remove(current, true);
  114. }
  115. } else {
  116. domUtils.remove(current, true);
  117. }
  118. } else {
  119. //trace:939 不能把list上的样式去掉
  120. if (
  121. !dtd.$tableContent[current.tagName] &&
  122. !dtd.$list[current.tagName]
  123. ) {
  124. domUtils.removeAttributes(current, removeFormatAttributes);
  125. if (isRedundantSpan(current)) {
  126. domUtils.remove(current, true);
  127. }
  128. }
  129. }
  130. }
  131. current = next;
  132. }
  133. }
  134. //trace:1035
  135. //trace:1096 不能把td上的样式去掉,比如边框
  136. var pN = bookmark.start.parentNode;
  137. if (
  138. domUtils.isBlockElm(pN) &&
  139. !dtd.$tableContent[pN.tagName] &&
  140. !dtd.$list[pN.tagName]
  141. ) {
  142. domUtils.removeAttributes(pN, removeFormatAttributes);
  143. }
  144. pN = bookmark.end.parentNode;
  145. if (
  146. bookmark.end &&
  147. domUtils.isBlockElm(pN) &&
  148. !dtd.$tableContent[pN.tagName] &&
  149. !dtd.$list[pN.tagName]
  150. ) {
  151. domUtils.removeAttributes(pN, removeFormatAttributes);
  152. }
  153. range.moveToBookmark(bookmark).moveToBookmark(bookmark1);
  154. //清除冗余的代码 <b><bookmark></b>
  155. var node = range.startContainer,
  156. tmp,
  157. collapsed = range.collapsed;
  158. while (
  159. node.nodeType == 1 &&
  160. domUtils.isEmptyNode(node) &&
  161. dtd.$removeEmpty[node.tagName]
  162. ) {
  163. tmp = node.parentNode;
  164. range.setStartBefore(node);
  165. //trace:937
  166. //更新结束边界
  167. if (range.startContainer === range.endContainer) {
  168. range.endOffset--;
  169. }
  170. domUtils.remove(node);
  171. node = tmp;
  172. }
  173. if (!collapsed) {
  174. node = range.endContainer;
  175. while (
  176. node.nodeType == 1 &&
  177. domUtils.isEmptyNode(node) &&
  178. dtd.$removeEmpty[node.tagName]
  179. ) {
  180. tmp = node.parentNode;
  181. range.setEndBefore(node);
  182. domUtils.remove(node);
  183. node = tmp;
  184. }
  185. }
  186. }
  187. range = this.selection.getRange();
  188. doRemove(range);
  189. range.select();
  190. }
  191. };
  192. };