searchreplace.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. ///import core
  2. ///commands 查找替换
  3. ///commandsName SearchReplace
  4. ///commandsTitle 查询替换
  5. ///commandsDialog dialogs\searchreplace
  6. /**
  7. * @description 查找替换
  8. * @author zhanyi
  9. */
  10. UE.plugin.register("searchreplace", function() {
  11. var me = this;
  12. var _blockElm = { table: 1, tbody: 1, tr: 1, ol: 1, ul: 1 };
  13. var lastRng = null;
  14. function getText(node) {
  15. var text = node.nodeType == 3
  16. ? node.nodeValue
  17. : node[browser.ie ? "innerText" : "textContent"];
  18. return text.replace(domUtils.fillChar, "");
  19. }
  20. function findTextInString(textContent, opt, currentIndex) {
  21. var str = opt.searchStr;
  22. var reg = new RegExp(str, "g" + (opt.casesensitive ? "" : "i")),
  23. match;
  24. if (opt.dir == -1) {
  25. textContent = textContent.substr(0, currentIndex);
  26. textContent = textContent.split("").reverse().join("");
  27. str = str.split("").reverse().join("");
  28. match = reg.exec(textContent);
  29. if (match) {
  30. return currentIndex - match.index - str.length;
  31. }
  32. } else {
  33. textContent = textContent.substr(currentIndex);
  34. match = reg.exec(textContent);
  35. if (match) {
  36. return match.index + currentIndex;
  37. }
  38. }
  39. return -1;
  40. }
  41. function findTextBlockElm(node, currentIndex, opt) {
  42. var textContent,
  43. index,
  44. methodName = opt.all || opt.dir == 1 ? "getNextDomNode" : "getPreDomNode";
  45. if (domUtils.isBody(node)) {
  46. node = node.firstChild;
  47. }
  48. var first = 1;
  49. while (node) {
  50. textContent = getText(node);
  51. index = findTextInString(textContent, opt, currentIndex);
  52. first = 0;
  53. if (index != -1) {
  54. return {
  55. node: node,
  56. index: index
  57. };
  58. }
  59. node = domUtils[methodName](node);
  60. while (node && _blockElm[node.nodeName.toLowerCase()]) {
  61. node = domUtils[methodName](node, true);
  62. }
  63. if (node) {
  64. currentIndex = opt.dir == -1 ? getText(node).length : 0;
  65. }
  66. }
  67. }
  68. function findNTextInBlockElm(node, index, str) {
  69. var currentIndex = 0,
  70. currentNode = node.firstChild,
  71. currentNodeLength = 0,
  72. result;
  73. while (currentNode) {
  74. if (currentNode.nodeType == 3) {
  75. currentNodeLength = getText(currentNode).replace(
  76. /(^[\t\r\n]+)|([\t\r\n]+$)/,
  77. ""
  78. ).length;
  79. currentIndex += currentNodeLength;
  80. if (currentIndex >= index) {
  81. return {
  82. node: currentNode,
  83. index: currentNodeLength - (currentIndex - index)
  84. };
  85. }
  86. } else if (!dtd.$empty[currentNode.tagName]) {
  87. currentNodeLength = getText(currentNode).replace(
  88. /(^[\t\r\n]+)|([\t\r\n]+$)/,
  89. ""
  90. ).length;
  91. currentIndex += currentNodeLength;
  92. if (currentIndex >= index) {
  93. result = findNTextInBlockElm(
  94. currentNode,
  95. currentNodeLength - (currentIndex - index),
  96. str
  97. );
  98. if (result) {
  99. return result;
  100. }
  101. }
  102. }
  103. currentNode = domUtils.getNextDomNode(currentNode);
  104. }
  105. }
  106. function searchReplace(me, opt) {
  107. var rng = lastRng || me.selection.getRange(),
  108. startBlockNode,
  109. searchStr = opt.searchStr,
  110. span = me.document.createElement("span");
  111. span.innerHTML = "$$ueditor_searchreplace_key$$";
  112. rng.shrinkBoundary(true);
  113. //判断是不是第一次选中
  114. if (!rng.collapsed) {
  115. rng.select();
  116. var rngText = me.selection.getText();
  117. if (
  118. new RegExp(
  119. "^" + opt.searchStr + "$",
  120. opt.casesensitive ? "" : "i"
  121. ).test(rngText)
  122. ) {
  123. if (opt.replaceStr != undefined) {
  124. replaceText(rng, opt.replaceStr);
  125. rng.select();
  126. return true;
  127. } else {
  128. rng.collapse(opt.dir == -1);
  129. }
  130. }
  131. }
  132. rng.insertNode(span);
  133. rng.enlargeToBlockElm(true);
  134. startBlockNode = rng.startContainer;
  135. var currentIndex = getText(startBlockNode).indexOf(
  136. "$$ueditor_searchreplace_key$$"
  137. );
  138. rng.setStartBefore(span);
  139. domUtils.remove(span);
  140. var result = findTextBlockElm(startBlockNode, currentIndex, opt);
  141. if (result) {
  142. var rngStart = findNTextInBlockElm(result.node, result.index, searchStr);
  143. var rngEnd = findNTextInBlockElm(
  144. result.node,
  145. result.index + searchStr.length,
  146. searchStr
  147. );
  148. rng
  149. .setStart(rngStart.node, rngStart.index)
  150. .setEnd(rngEnd.node, rngEnd.index);
  151. if (opt.replaceStr !== undefined) {
  152. replaceText(rng, opt.replaceStr);
  153. }
  154. rng.select();
  155. return true;
  156. } else {
  157. rng.setCursor();
  158. }
  159. }
  160. function replaceText(rng, str) {
  161. str = me.document.createTextNode(str);
  162. rng.deleteContents().insertNode(str);
  163. }
  164. return {
  165. commands: {
  166. searchreplace: {
  167. execCommand: function(cmdName, opt) {
  168. utils.extend(
  169. opt,
  170. {
  171. all: false,
  172. casesensitive: false,
  173. dir: 1
  174. },
  175. true
  176. );
  177. var num = 0;
  178. if (opt.all) {
  179. lastRng = null;
  180. var rng = me.selection.getRange(),
  181. first = me.body.firstChild;
  182. if (first && first.nodeType == 1) {
  183. rng.setStart(first, 0);
  184. rng.shrinkBoundary(true);
  185. } else if (first.nodeType == 3) {
  186. rng.setStartBefore(first);
  187. }
  188. rng.collapse(true).select(true);
  189. if (opt.replaceStr !== undefined) {
  190. me.fireEvent("saveScene");
  191. }
  192. while (searchReplace(this, opt)) {
  193. num++;
  194. lastRng = me.selection.getRange();
  195. lastRng.collapse(opt.dir == -1);
  196. }
  197. if (num) {
  198. me.fireEvent("saveScene");
  199. }
  200. } else {
  201. if (opt.replaceStr !== undefined) {
  202. me.fireEvent("saveScene");
  203. }
  204. if (searchReplace(this, opt)) {
  205. num++;
  206. lastRng = me.selection.getRange();
  207. lastRng.collapse(opt.dir == -1);
  208. }
  209. if (num) {
  210. me.fireEvent("saveScene");
  211. }
  212. }
  213. return num;
  214. },
  215. notNeedUndo: 1
  216. }
  217. },
  218. bindEvents: {
  219. clearlastSearchResult: function() {
  220. lastRng = null;
  221. }
  222. }
  223. };
  224. });