Range.js 89 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582
  1. module('core.Range');
  2. var checkBookmark = function (bookmark, pre, latter, id) {
  3. same(bookmark['start'], pre, '检查start返回值');
  4. same(bookmark['end'], latter, '检查end返回值');
  5. equal(bookmark['id'], id, '检查id');
  6. };
  7. test('init', function () {
  8. expect(6);
  9. var div = te.dom[2];
  10. var range = new baidu.editor.dom.Range(document);
  11. ua.checkResult(range, null, null, null, null, true, 'for init range');
  12. same(range.document, document, 'check current document of range');
  13. });
  14. test('setStart/startEnd 自闭合元素', function () {
  15. var range = new baidu.editor.dom.Range(document);
  16. var div = te.dom[2];
  17. var img = document.createElement('img');
  18. div.appendChild(img);
  19. range.setStart(img, 0);
  20. ua.checkResult(range, div, div, 0, 0, true, "endContainer is null");
  21. range.setEnd(img, 0);
  22. ua.checkResult(range, div, div, 0, 1, false, "startContainer is not null");
  23. range.startContainer = null;
  24. range.setEnd(img, 0);
  25. ua.checkResult(range, div, div, 1, 1, true, "startContainer is null");
  26. range.setStart(img, 0);
  27. ua.checkResult(range, div, div, 0, 1, false, "endContainer is not null");
  28. });
  29. test('setStart/startEnd--nodeType不为1', function () {
  30. var range = new baidu.editor.dom.Range(document);
  31. var div = te.dom[2];
  32. var text = document.createTextNode("text");
  33. div.appendChild(text);
  34. range.setStart(text, 0);
  35. ua.checkResult(range, text, text, 0, 0, true, "endContainer is null");
  36. range.setEnd(text, 1);
  37. ua.checkResult(range, text, text, 0, 1, false, "startContainer is not null");
  38. });
  39. test('setStart/setEnd--nodeType为1', function () {
  40. var range = new baidu.editor.dom.Range(document);
  41. var div = te.dom[2];
  42. range.setStart(div, 0);
  43. ua.checkResult(range, div, div, 0, 0, true, "endContainer is null");
  44. range.setEnd(div, 1);
  45. ua.checkResult(range, div, div, 0, 1, false, "startContainer is not null");
  46. });
  47. /*
  48. * 测的内容比较多,updateCollapse,setEndPoint,setStart,setEnd,collapse
  49. * 因为updateCollapse和setEndPoint无法通过Range对象获取, 必须间接调用验证
  50. */
  51. test('setStartAfter,setStartBefore', function () {
  52. var div = te.dom[2];
  53. div.innerHTML = '<span></span><a></a>';
  54. var span = div.firstChild;
  55. var a = div.lastChild;
  56. var range = new baidu.editor.dom.Range(document);
  57. range.setStartAfter(a);
  58. equal(range.startOffset, 2, 'check startOffset for setStartAfter--boundary testing');
  59. range.setStartAfter(span);
  60. equal(range.startOffset, 1, 'check startOffset for setStartAfter');
  61. range.setStartBefore(span);
  62. equal(range.startOffset, 0, 'check startOffset for setStartBefore--boundary testing');
  63. range.setStartBefore(a);
  64. equal(range.startOffset, 1, 'check startOffset for setStartBefore');
  65. var txtNode = document.createTextNode("text");
  66. div.innerHTML = "";
  67. div.appendChild(txtNode);
  68. range.setStartBefore(txtNode);
  69. equal(range.startOffset, 0, 'check startOffset in text node');
  70. });
  71. test('setEndAfter,setEndBefore', function () {
  72. var div = te.dom[2];
  73. div.innerHTML = '<span></span><a></a>';
  74. var span = div.firstChild;
  75. var a = div.lastChild;
  76. var range = new baidu.editor.dom.Range(document);
  77. range.setEndAfter(a);
  78. equal(range.endOffset, 2, 'check startOffset for setEndAfter--boundary testing');
  79. range.setEndAfter(span);
  80. equal(range.endOffset, 1, 'check startOffset for setEndAfter');
  81. range.setEndBefore(span);
  82. equal(range.endOffset, 0, 'check startOffset for setEndBefore--boundary testing');
  83. range.setEndBefore(a);
  84. equal(range.endOffset, 1, 'check startOffset for setEndBefore');
  85. });
  86. /* 校验collapse方法 */
  87. test('collapse', function () {
  88. var text = document.createTextNode('TextNode');
  89. te.dom[2].appendChild(text);
  90. var range = new baidu.editor.dom.Range(document);
  91. range.setStart(text, 1);
  92. // ua.checkResult(range.endContainer,range.startContainer,0)
  93. ok(range.collapsed, 'check collapse method true--setStart');
  94. equal(range.startContainer, range.endContainer, 'compare startContainer and endContainer--setStart');
  95. range.startContainer = null;
  96. range.setEnd(text, 0);
  97. equal(range.startContainer, range.endContainer, 'compare startContainer and endContainer--setEnd');
  98. equal(range.startOffset, range.endOffset, 'compare startOffset and endOffset--setEnd');
  99. ok(range.collapsed, 'check collapsed is true--setEnd');
  100. var img = document.createElement("img");
  101. range.insertNode(img).selectNode(img);
  102. equal(range.startContainer, range.endContainer, "img startContainer and endContainer is same,but startOffset and endOffset is not same");
  103. });
  104. //TODO 空节点<div></div>
  105. test('selectNode', function () {
  106. var div = te.dom[2];
  107. div.innerHTML = "text!";
  108. div.id = 'div_id';
  109. var range = new baidu.editor.dom.Range(document);
  110. range.selectNode(div);
  111. var index = ua.getIndex(div);
  112. ua.checkResult(range, document.body, document.body, index, index + 1, false, 'check selectNode');
  113. });
  114. test('selectNode--空节点', function () {
  115. var div = te.dom[2];
  116. var range = new baidu.editor.dom.Range(document);
  117. range.selectNode(div);
  118. var index = ua.getIndex(div);
  119. ua.checkResult(range, document.body, document.body, index, index + 1, false, 'check selectNode');
  120. });
  121. test('selectNode--空文本节点', function () {
  122. var div = te.dom[2];
  123. var range = new baidu.editor.dom.Range(document);
  124. var textNode = document.createTextNode('');
  125. div.appendChild(textNode);
  126. range.selectNode(div);
  127. var index = ua.getIndex(div);
  128. ua.checkResult(range, document.body, document.body, index, index + 1, false, 'check selectNode');
  129. });
  130. test('selectNodeContents', function () {
  131. expect(15);
  132. var div = te.dom[2];
  133. div.innerHTML = '<div>text</div><a>';
  134. var text = div.firstChild.firstChild;
  135. var range = new baidu.editor.dom.Range(document);
  136. range = range.selectNodeContents(div);
  137. ua.checkResult(range, div, div, 0, 2, false, 'selectNodeContents');
  138. /*textNode*/
  139. range = range.selectNodeContents((text));
  140. ua.checkResult(range, text, text, 0, 4, false, 'selectNodeContents for textNode');
  141. div.innerHTML = '<b>xxx<i>xxx</i>xxx</b>';
  142. range = new baidu.editor.dom.Range(document);
  143. range = range.selectNodeContents(div.firstChild);
  144. ua.checkResult(range, div.firstChild, div.firstChild, 0, 3, false, 'selectNodeContents');
  145. });
  146. test('cloneRange', function () {
  147. expect(5);
  148. var div = te.dom[2];
  149. var range = new baidu.editor.dom.Range(document);
  150. div.innerHTML = '<div>cloneRange</div>';
  151. range.setStart(div, 0);
  152. range.setEnd(div, 1);
  153. var cloneRange = range.cloneRange(range);
  154. ua.checkResult(range, cloneRange.startContainer, cloneRange.endContainer,
  155. cloneRange.startOffset, cloneRange.endOffset, false, 'cloneRange');
  156. });
  157. /*循环缩进子节点,直到子节点元素类型不为1或为自闭合元素*/
  158. test('shrinkBoundary--not ignore end', function () {
  159. var div = te.dom[2];
  160. var range = new baidu.editor.dom.Range(document);
  161. // $('#test').css('background','red');
  162. div.innerHTML = '<div>div1_text</div><a>a_text</a><div><span>span_text</span>div3_text</div>';
  163. var a = div.firstChild.nextSibling;
  164. var div_2 = div.lastChild;
  165. range.setStart(div, 1).setEnd(div, 3);
  166. range.shrinkBoundary();
  167. ua.checkResult(range, a, div_2, 0, 2, false, 'shrinkBoundary--not ignore end');
  168. });
  169. test('shrinkBoundary--ignoreEnd', function () {
  170. var div = te.dom[2];
  171. var range = new baidu.editor.dom.Range(document);
  172. div.innerHTML = "<div><p>p_text</p></div>";
  173. var div_child = div.firstChild;
  174. var p = div_child.firstChild;
  175. range.setStart(div_child, 0).setEnd(div_child, 0);
  176. //TODO
  177. range.shrinkBoundary(true);
  178. ua.checkResult(range, p, p, 0, 0, true, '检查前后闭合是否一致');
  179. });
  180. test('shrinkBonudaryl', function () {
  181. var div = te.dom[2];
  182. var range = new baidu.editor.dom.Range(document);
  183. div.innerHTML = '<b><i>xxxx</i>xxxxxxx</b>';
  184. /*ignoreEnd=true*/
  185. range.selectNodeContents(div).shrinkBoundary(true);
  186. var i = div.firstChild.firstChild;
  187. ua.checkResult(range, i, div, 0, 1, false, 'shrinkBoundary--ignoreEnd');
  188. /*ignoreEnd = null*/
  189. var b = div.firstChild;
  190. range.selectNodeContents(div).shrinkBoundary();
  191. ua.checkResult(range, i, b, 0, b.childNodes.length, false, 'shrinkBoundary--not ignoreEnd');
  192. div.innerHTML = 'xxxx<b><i><u></u></i></b>ssss';
  193. var u = div.getElementsByTagName('u')[0];
  194. range.selectNode(div.getElementsByTagName('b')[0]).shrinkBoundary();
  195. ua.checkResult(range, u, u, 0, 0, true, '初始startContainer和endContainer相同');
  196. div.innerHTML = '<table><tr><td>sssss</td></tr></table>';
  197. var td = div.getElementsByTagName('td')[0];
  198. var table = div.firstChild;
  199. range.setStart(table, 0).setEnd(table.getElementsByTagName('tr')[0], 1).shrinkBoundary();
  200. ua.checkResult(range, td, td, 0, 1, false, '初始startContainer和endContainer不同');
  201. div.innerHTML = '<img/>';
  202. range.setStart(div, 0).setEnd(div, 1).shrinkBoundary();
  203. ua.checkResult(range, div, div, 0, 1, false, '子节点为自闭合元素,未能进入函数内部的逻辑');
  204. div.innerHTML = 'text';
  205. var text = div.firstChild;
  206. range.setStart(text, 1).setEnd(text, 4).shrinkBoundary();
  207. ua.checkResult(range, text, text, 1, 4, false, '节点为文本节点,未能进入函数内部的逻辑');
  208. range.setStart(div, 0).setEnd(div, 1).shrinkBoundary();
  209. ua.checkResult(range, div, div, 0, 1, false, '子节点为文本节点,未能进入函数内部的逻辑');
  210. range.setStart(div, 0).setEnd(div, 0).shrinkBoundary();
  211. ua.checkResult(range, div, div, 0, 0, true, '元素collapsed');
  212. range.setStart(div, 0).setEnd(text, 4).shrinkBoundary();
  213. ua.checkResult(range, div, text, 0, 4, false, 'endContainer为文本节点');
  214. });
  215. /*调整边界,针对TextNode*/
  216. test('txtToElmBoundary', function () {
  217. var div = te.dom[2];
  218. div.innerHTML = 'text_node';
  219. var range = new baidu.editor.dom.Range(document);
  220. var text = div.firstChild;
  221. /*endOffset大于text的长度*/
  222. range.setStart(text, 0).setEnd(text, 10);
  223. range.txtToElmBoundary();
  224. ua.checkResult(range, div, div, 0, 1, false, 'endOffset大于text的长度');
  225. /*endOffset小于text的长度*/
  226. range.setStart(text, 1).setEnd(text, 4).txtToElmBoundary();
  227. ua.checkResult(range, text, text, 1, 4, false, 'endOffset小于text长度');
  228. range.setStart(text, 1).setEnd(text, 10).txtToElmBoundary();
  229. ua.checkResult(range, text, div, 1, 1, false, 'startOffset不为0,endOffset大于text长度');
  230. /*startOffset和endOffset都大于text长度*/
  231. range.setStart(text, 10).setEnd(text, 11).txtToElmBoundary();
  232. ua.checkResult(range, div, div, 1, 1, true, 'endOffset和startOffset大于text长度');
  233. /*startOffset和endOffset都等于0*/
  234. range.setStart(text, 0).setEnd(text, 0).txtToElmBoundary();
  235. ua.checkResult(range, text, text, 0, 0, true, 'startOffset和endOffset为0');
  236. });
  237. /*切分文本节点*/
  238. test('trimBonudary', function () {
  239. var div = te.dom[2];
  240. div.innerHTML = '<table border="1"><tr><td>td_xxxx<b><i><u>u_text</u></i></b></td></tr></table>';
  241. var range = new baidu.editor.dom.Range(document);
  242. var td = div.getElementsByTagName('td')[0];
  243. var td_text = td.firstChild;
  244. /*startOffset为0,在第一个孩子节点前插入*/
  245. range.setStart(td_text, 0).setEnd(td_text, 5);
  246. range.trimBoundary();
  247. ua.checkResult(range, td, td, 0, 1, false, '切分文本节点');
  248. /*text_node被切分为2个文本节点*/
  249. equal(td_text.data, "td_xx", "check text of tr");
  250. var u = div.getElementsByTagName('u')[0];
  251. var u_text = u.firstChild;
  252. /*startOffset=0 && collapsed=true,则不对后面的文本节点进行操作*/
  253. range.setStart(u_text, 0).setEnd(u_text, 0);
  254. range.trimBoundary();
  255. ua.checkResult(range, u, u, 0, 0, true, 'startOffset=endOffset=0');
  256. /*endOffset大于text的长度,从左边切'*/
  257. range.setStart(u_text, 3).setEnd(u_text, 10);
  258. range.trimBoundary().select();
  259. ua.checkResult(range, u, u, 1, 2, false, 'endOffset大于text的长度');
  260. equal(u_text.data, 'u_t', '从左边切分textNode');
  261. /*endOffset大小于text的长度,从中间切'*/
  262. range.setStart(u_text, 1).setEnd(u_text, 2);
  263. range.trimBoundary();
  264. ua.checkResult(range, u, u, 1, 2, false, 'endOffset小于text的长度');
  265. equal(u_text.data, 'u', '从中间切分textNode');
  266. div.innerHTML = '123456';
  267. range.setStart(div.firstChild, 2).setEnd(div.firstChild, 4).trimBoundary(true);
  268. ua.checkResult(range, div, div.lastChild, 1, 2, false, 'ignoreEnd');
  269. });
  270. /*前面尽可能往右边跳,后面尽可能往左边跳*/
  271. test('adjustmentBoundary--startContainer为文本节点', function () {
  272. var range = new baidu.editor.dom.Range(document);
  273. var div = te.dom[2];
  274. div.innerHTML = 'div_text<p><span id="span">span_text</span></p>div_text2<p id="p">p_text<em>em_text</em></p>';
  275. var span_text = document.getElementById('span').firstChild;
  276. var p = document.getElementById('p');
  277. range.setStart(span_text, 9).setEnd(p, 0);
  278. range.adjustmentBoundary();
  279. ua.checkResult(range, div, div, 2, 3, false, 'startContainer为文本节点');
  280. });
  281. //TODO
  282. test('adjustmentBoundary--非文本节点', function () {
  283. var range = new baidu.editor.dom.Range(document);
  284. var div = te.dom[2];
  285. div.innerHTML = 'div_text<p><span id="span">span_text</span></p>div_text2<p id="p">p_text<em>em_text</em></p>';
  286. var span = document.getElementById('span');
  287. var p = document.getElementById('p');
  288. range.setStart(span, 1).setEnd(p, 0);
  289. range.adjustmentBoundary();
  290. ua.checkResult(range, div, div, 2, 3, false, 'startContainer为非文本节点');
  291. });
  292. test('getCommonAncestor--初始startContainer和endContainer相同', function () {
  293. var range = new baidu.editor.dom.Range(document);
  294. var div = te.dom[2];
  295. div.innerHTML = "div_text<p><span>span_text</span></p>div_text2";
  296. range.setStart(div, 0).setEnd(div, 1);
  297. /*--初始startContainer和endContainer相同*/
  298. var ancestor = range.getCommonAncestor();
  299. same(ancestor, div, '祖先节点为startContainer');
  300. /*文本节点*/
  301. var span = div.getElementsByTagName('span')[0];
  302. range.setStart(span.firstChild, 0).setEnd(span.firstChild, 4);
  303. ancestor = range.getCommonAncestor();
  304. same(ancestor, span.firstChild, "文本节点的祖先节点");
  305. /*忽略文本节点*/
  306. ancestor = range.getCommonAncestor(true, true);
  307. same(ancestor, span, "文本节点的祖先节点--忽略文本节点");
  308. range.setStart(div, 1).setEnd(div, 2);
  309. ancestor = range.getCommonAncestor(true, true);
  310. same(ancestor, span.parentNode, "文本节点的祖先节点--includeSelf=true");
  311. range.setStart(div, 1).setEnd(div, 2);
  312. ancestor = range.getCommonAncestor(false, true);
  313. same(ancestor, div, "文本节点的祖先节点--includeSelf=false");
  314. });
  315. test('getCommonAncestor--初始startContainer和endContainer不同', function () {
  316. var range = new baidu.editor.dom.Range(document);
  317. var div = te.dom[2];
  318. div.innerHTML = "div_text<p><span>span_text</span></p>div_text2";
  319. var span = div.getElementsByTagName('span')[0];
  320. range.setStart(div, 0).setEnd(span, 1);
  321. /*--初始startContainer和endContainer相同*/
  322. var ancestor = range.getCommonAncestor();
  323. same(ancestor, div, 'startContainer是endContainer的祖先');
  324. range.setStart(div.firstChild, 0).setEnd(span, 1);
  325. ancestor = range.getCommonAncestor();
  326. same(ancestor, div, 'startContainer和endContainer是兄弟');
  327. });
  328. test('selectNodeContents', function () {
  329. var div = te.dom[2];
  330. div.innerHTML = '<b>xxxx</b>div_text';
  331. var range = new baidu.editor.dom.Range(document);
  332. /*选中非文本节点*/
  333. range.selectNodeContents(div);
  334. ua.checkResult(range, div, div, 0, 2, false, 'selectNodeContents');
  335. /*选中文本节点*/
  336. range.selectNodeContents(div.lastChild);
  337. ua.checkResult(range, div.lastChild, div.lastChild, 0, 8, false, 'selectNodeContents--');
  338. });
  339. test('cloneContents', function () {
  340. var div = te.dom[2];
  341. div.innerHTML = '<b>b_text</b>div_text';
  342. // div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  343. var range = new baidu.editor.dom.Range(document);
  344. var b = div.firstChild;
  345. range.setStart(b, 1).setEnd(div, 1);
  346. var frag = range.cloneContents();
  347. /*类型:<b>xxxx|</b>|div_text("|"表示切的位置)*/
  348. equal(ua.getHTML(frag), '<b></b>', ' 只选中一个b标签,插入空文本节点');
  349. /*类型:<b>t|_ext</b>div|_text("|"表示切的位置)*/
  350. range.setStart(b.firstChild, 1).setEnd(b.nextSibling, 3);
  351. frag = range.cloneContents();
  352. equal(ua.getHTML(frag), '<b>_text</b>div', '从文本节点中间切');
  353. /*类型:|<b>b_t|ext</b>div_text("|"表示切的位置)*/
  354. range.setStart(div, 0).setEnd(b.firstChild, 3);
  355. frag = range.cloneContents();
  356. equal(ua.getHTML(frag), '<b>b_t</b>', '选中文本的前半部分');
  357. /*类型:<b>b|_text</b>div_text|("|"表示切的位置)*/
  358. range.setStart(b.firstChild, 1).setEnd(div, 2);
  359. frag = range.cloneContents();
  360. equal(ua.getHTML(frag), '<b>_text</b>div_text', '选中文本的前半部分');
  361. /*类型:<b>xxxx|</b>xxxx<b>c22c|</b>("|"表示切的位置)*/
  362. div.innerHTML = '<b>xxxx</b>xxxx<b>c22c</b>';
  363. range.setStart(div.firstChild, 1).setEnd(div.lastChild, 1);
  364. equals(ua.getHTML(range.cloneContents()), '<b></b>xxxx<b>c22c</b>');
  365. });
  366. /*startContainer和endContainer为文本节点,补全后面</b></tr>之类的标签*/
  367. test('cloneContents--补全后面的标签', function () {
  368. var div = te.dom[2];
  369. var r = new baidu.editor.dom.Range(document);
  370. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  371. var first = document.getElementById('first').firstChild;
  372. var two = document.getElementById('two').firstChild;
  373. r.setStart(first, 1).setEnd(two, 2);
  374. ua.checkSameHtml(ua.getHTML(r.cloneContents()), '<p id="first">irst<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b><em>em text</em>more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">ab</td></tr></tbody></table>');
  375. ua.checkResult(r, first, two, 1, 2, false, 'cloneContents--补全后面的标签');
  376. });
  377. /*startContainer和endContainer为文本节点,层级各不相同,补全前面 的<b><tr>之类的标签*/
  378. test('cloneContents--补全前面的标签', function () {
  379. var div = te.dom[2];
  380. var r = new baidu.editor.dom.Range(document);
  381. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  382. var last = document.getElementById('last').firstChild;
  383. var two = document.getElementById('two').firstChild;
  384. r.setStart(two, 1);
  385. r.setEnd(last, 2);
  386. ua.checkSameHtml(ua.getHTML(r.cloneContents()), '<table id="table" width="300"><tbody><tr><td id="two">bc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">te</p>');
  387. ua.checkResult(r, two, last, 1, 2, false, 'cloneContents--补全前面的标签');
  388. });
  389. /*startContainer和endContainer为文本节点,为兄弟节点*/
  390. test('cloneContents--切的部分为兄弟节点', function () {
  391. var div = te.dom[2];
  392. var r = new baidu.editor.dom.Range(document);
  393. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  394. var first = document.getElementById('first');
  395. r.setStart(first.firstChild, 1).setEnd(first.lastChild, 4);
  396. /*strong前面有空格*/
  397. ua.checkSameHtml(ua.getHTML(r.cloneContents()), 'irst<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> str');
  398. ua.checkResult(r, first.firstChild, first.lastChild, 1, 4, false, 'cloneContents--startContainer和endContainer为兄弟节点');
  399. });
  400. test('cloneContents--切同一个文本节点', function () {
  401. var div = te.dom[2];
  402. var r = new baidu.editor.dom.Range(document);
  403. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  404. var first = document.getElementById('first').firstChild;
  405. r.setStart(first, 1).setEnd(first, 4);
  406. equals(ua.getHTML(r.cloneContents()), 'irs');
  407. ua.checkResult(r, first, first, 1, 4, false, 'cloneContents--切同一个文本节点');
  408. });
  409. /*startContainer和endContainer的nodeType=1*/
  410. test('cloneContents--startContainer和endContainer为非文本节点', function () {
  411. var div = te.dom[2];
  412. var r = new baidu.editor.dom.Range(document);
  413. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  414. var first = document.getElementById('first');
  415. var last = document.getElementById('last');
  416. r.setStart(first, 0).setEnd(last, 0);
  417. ua.checkSameHtml(ua.getHTML(r.cloneContents()), '<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b><em>em text</em>more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\"></p>');
  418. ua.checkResult(r, first, last, 0, 0, false, 'cloneContents--开始和结束位置都是文本');
  419. r.setStart(first, 1).setEnd(last, 1);
  420. ua.checkSameHtml(ua.getHTML(r.cloneContents()), '<p id="first"><!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b><em>em text</em>more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc</p>');
  421. ua.checkResult(r, first, last, 1, 1, false, 'cloneContents--开始位置有注释');
  422. });
  423. test('cloneContents--完整切掉一个节点', function () {
  424. var div = te.dom[2];
  425. var r = new baidu.editor.dom.Range(document);
  426. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  427. var first = document.getElementById('first');
  428. r.setStart(div, 0).setEnd(div, div.childNodes.length - 1);
  429. ua.checkSameHtml(ua.getHTML(r.cloneContents()), '<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b><em>em text</em>more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table>');
  430. ua.checkResult(r, div, div, 0, div.childNodes.length - 1, false, 'cloneContents--完整切掉一个节点');
  431. });
  432. test('cloneContents--startContainer和endContainer节点类型不同', function () {
  433. var div = te.dom[2];
  434. var r = new baidu.editor.dom.Range(document);
  435. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  436. var first = document.getElementById('first');
  437. var last = document.getElementById('last');
  438. r.setStart(first, 0).setEnd(last.firstChild, 1);
  439. ua.checkSameHtml(ua.getHTML(r.cloneContents()), '<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b><em>em text</em>more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">t</p>');
  440. ua.checkResult(r, first, last.firstChild, 0, 1, false, 'cloneContents--startContainer的nodeType=1,endContainer为文本节点');
  441. r.setStart(first.firstChild, 1).setEnd(last, 0);
  442. ua.checkSameHtml(ua.getHTML(r.cloneContents()), '<p id="first">irst<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b><em>em text</em>more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last"></p>');
  443. ua.checkResult(r, first.firstChild, last, 1, 0, false, 'cloneContents--endContainer为文本节点,startContainer的nodeType=1');
  444. });
  445. test('cloneContents--endContainer为em', function () {
  446. var div = te.dom[2];
  447. var r = new baidu.editor.dom.Range(document);
  448. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  449. var traverse = document.getElementById('traverse');
  450. r.setStart(div, 0).setEnd(traverse, 1);
  451. equals(ua.getHTML(r.cloneContents()), '<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b></p>');
  452. ua.checkResult(r, div, traverse, 0, 1, false, 'cloneContents--startContainer的nodeType=1,endContainer为b');
  453. r.setStart(div, 0).setEnd(traverse, 2);
  454. equals(ua.getHTML(r.cloneContents()), '<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b><em>em text</em></p>');
  455. ua.checkResult(r, div, traverse, 0, 2, false, 'cloneContents--startContainer的nodeType=1,endContainer为em');
  456. });
  457. test('cloneContents--元素闭合', function () {
  458. var div = te.dom[2];
  459. var range = new baidu.editor.dom.Range(document);
  460. div.innerHTML = '<p>p_text</p>';
  461. // if ( baidu.editor.browser.gecko ) {
  462. var text = div.firstChild.firstChild;
  463. range.setStart(text, 1).setEnd(text, 1);
  464. equals(ua.getHTML(range.cloneContents()), 'null', '元素闭合直接返回null');
  465. ua.checkResult(range, text, text, 1, 1, true, 'cloneContents--startContainer的nodeType=1,endContainer为em');
  466. var p = div.firstChild;
  467. range.setStart(p, 1).setEnd(p, 1);
  468. equals(ua.getHTML(range.cloneContents()), 'null', '元素闭合直接返回null');
  469. ua.checkResult(range, p, p, 1, 1, true, 'cloneContents--startContainer的nodeType=1,endContainer为em');
  470. });
  471. test('cloneContents--自闭合元素', function () {
  472. var div = te.dom[2];
  473. var range = new baidu.editor.dom.Range(document);
  474. div.innerHTML = '<b>b_text<i id="ii">i_text</i><img /></b>xxx';
  475. var b = div.firstChild;
  476. range.setStart(b.firstChild, 2).setEnd(b, b.childNodes.length);
  477. /*只能获得<img>而不是<img />的标签*/
  478. equal(ua.getHTML(range.cloneContents()), 'text<i id="ii">i_text</i><img>');
  479. ua.checkResult(range, b.firstChild, b, 2, b.childNodes.length, false, '选中结束位置为自闭合元素-1');
  480. var i = b.firstChild.nextSibling;
  481. range.setStart(i, 1).setEnd(b, b.childNodes.length);
  482. equal(ua.getHTML(range.cloneContents()), '<i id="ii"></i><img>');
  483. ua.checkResult(range, i, b, 1, b.childNodes.length, false, '选中结束位置为自闭合元素-2');
  484. range.setStart(i.firstChild, 2).setEnd(div, 2);
  485. equal(ua.getHTML(range.cloneContents()), '<b><i id="ii">text</i><img></b>xxx');
  486. ua.checkResult(range, i.firstChild, div, 2, 2, false, '选中结束位置为自闭合元素-3');
  487. div.innerHTML = 'xxx<b>xxxx<i id="ii">i_Text</i><img/></b>xxx';
  488. var i_text = document.getElementById('ii').firstChild;
  489. range.setStart(div, 0).setEnd(i_text, 2);
  490. equals(ua.getHTML(range.cloneContents()), 'xxx<b>xxxx<i id="ii">i_</i></b>');
  491. ua.checkResult(range, div, i_text, 0, 2, false, '选中结束位置为自闭合元素-4');
  492. });
  493. test('deleteContents--删除空', function () {
  494. var div = te.dom[2];
  495. var range = new baidu.editor.dom.Range(document);
  496. div.innerHTML = '<p>p_text</p>';
  497. var p_text = div.firstChild.firstChild;
  498. range.setStart(p_text, 2).setEnd(p_text, 2);
  499. range.deleteContents();
  500. ua.checkResult(range, p_text, p_text, 2, 2, true, '删除空');
  501. equal(ua.getHTML(div), '<div id="test"><p>p_text</p></div>', 'div的innerHTML没有改变 ');
  502. });
  503. test('deleteContents--删除相邻节点之间的内容', function () {
  504. var div = te.dom[2];
  505. var html = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  506. div.innerHTML = html;
  507. var r = new baidu.editor.dom.Range(document);
  508. var two = document.getElementById('two');
  509. var last = document.getElementById('last');
  510. r.setStart(two, 1).setEnd(last, 2);
  511. r.deleteContents();
  512. ua.checkSameHtml(ua.getHTML(div), '<div id="test"><p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b><em>em text</em>more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr></tbody></table><p id="last"></p></div>');
  513. ua.checkResult(r, div, div, 4, 4, true, '删除相邻节点的内容');
  514. });
  515. test('deleteContents--删除子节点', function () {
  516. var div = te.dom[2];
  517. var html = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  518. div.innerHTML = html;
  519. var r = new baidu.editor.dom.Range(document);
  520. r.setStart(div, 0).setEnd(div, 2);
  521. r.deleteContents();
  522. ua.checkSameHtml(ua.getHTML(r.startContainer), '<div id="test"><p id="traverse"><b><em id="em">some text</em></b><em>em text</em>more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
  523. ua.checkResult(r, div, div, 0, 0, true, '删除子节点的内容');
  524. });
  525. test('deleteContents--删除同一文本节点内容', function () {
  526. var div = te.dom[2];
  527. var html = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  528. div.innerHTML = html;
  529. var r = new baidu.editor.dom.Range(document);
  530. var p = div.firstChild;
  531. var strong_text = document.getElementById('strong').firstChild;
  532. r.setStart(strong_text, 0).setEnd(strong_text, 2);
  533. r.deleteContents();
  534. equals(ua.getHTML(r.startContainer), 'rong');
  535. ua.checkSameHtml(ua.getHTML(div), '<div id="test"><p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">rong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p></div>');
  536. ua.checkResult(r, strong_text, strong_text, 0, 0, true, '删除子节点的内容');
  537. });
  538. test('deleteContents--startContainer是endContainer父亲', function () {
  539. var div = te.dom[2];
  540. var r = new baidu.editor.dom.Range(document);
  541. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  542. r.setStart(div, 0);
  543. r.setEnd(document.getElementById('traverse'), 2);
  544. r.deleteContents();
  545. ua.checkSameHtml(ua.getHTML(div), '<div id="test"><p id="traverse">more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
  546. ua.checkResult(r, div, div, 0, 0, true, 'startContainer是endContainer父亲');
  547. });
  548. test('deleteContents--startContainer和endContainer为不同文本节点', function () {
  549. var div = te.dom[2];
  550. var html = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  551. div.innerHTML = html;
  552. var r = new baidu.editor.dom.Range(document);
  553. var first = document.getElementById('first');
  554. r.setStart(first.firstChild, 1).setEnd(first.lastChild, 4);
  555. var p = div.firstChild;
  556. r.deleteContents();
  557. equals(ua.getHTML(r.startContainer), '<p id="first">fong.</p>');
  558. ua.checkResult(r, p, p, 1, 1, true, 'startContainer和endContainer为文本节点内容');
  559. ua.checkSameHtml(ua.getHTML(div), '<div id="test"><p id="first">fong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b><em>em text</em>more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
  560. equals(ua.getHTML(r.endContainer), '<p id="first">fong.</p>');
  561. });
  562. test('deleteContents--startContainer是endContainer后代', function () {
  563. var div = te.dom[2];
  564. var html = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  565. div.innerHTML = html;
  566. var r = new baidu.editor.dom.Range(document);
  567. var em = document.getElementById('em');
  568. r.setStart(em, 1).setEnd(div, 3);
  569. r.deleteContents();
  570. ua.checkSameHtml(ua.getHTML(r.startContainer), '<div id="test"><p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em></p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p></div>');
  571. ua.checkResult(r, div, div, 1, 1, true, 'startContainer是endContainer后代');
  572. });
  573. test('deleteContents--startContainer是文本,endContainer的nodeType=1', function () {
  574. var div = te.dom[2];
  575. var html = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  576. div.innerHTML = html;
  577. var r = new baidu.editor.dom.Range(document);
  578. var em = document.getElementById('em').firstChild;
  579. var two = document.getElementById('two');
  580. r.setStart(em, 1).setEnd(two, 0);
  581. r.deleteContents();
  582. ua.checkSameHtml(ua.getHTML(r.startContainer), '<div id="test"><p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">e</em></p><table id=\"table\" width=\"300\"><tbody><tr><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p></div>');
  583. ua.checkResult(r, div, div, 1, 1, true, 'startContainer是文本,endContainer的nodeType=1');
  584. });
  585. /*startContainer和endContainer为文本节点,补全后面</b></tr>之类的标签*/
  586. test('extractContents--补全后面的标签', function () {
  587. var div = te.dom[2];
  588. var r = new baidu.editor.dom.Range(document);
  589. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  590. var first = document.getElementById('first').firstChild;
  591. var two = document.getElementById('two').firstChild;
  592. r.setStart(first, 1).setEnd(two, 2);
  593. ua.checkSameHtml(ua.getHTML(r.extractContents()), '<p id="first">irst<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b><em>em text</em>more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">ab</td></tr></tbody></table>');
  594. ua.checkSameHtml(ua.getHTML(r.startContainer), '<div id="test"><p id=\"first\">f</p><table id=\"table\" width=\"300\"><tbody><tr><td id=\"two\">c</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p></div>');
  595. ua.checkResult(r, div, div, 1, 1, true, 'startContainer--补全后面的标签');
  596. });
  597. /*startContainer和endContainer为文本节点,层级各不相同,补全前面 的<b><tr>之类的标签*/
  598. test('extractContents--补全前面的标签', function () {
  599. var div = te.dom[2];
  600. var r = new baidu.editor.dom.Range(document);
  601. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  602. var last = document.getElementById('last').firstChild;
  603. var two = document.getElementById('two').firstChild;
  604. r.setStart(two, 1).setEnd(last, 2);
  605. ua.checkSameHtml(ua.getHTML(r.extractContents()), '<table id="table" width="300"><tbody><tr><td id="two">bc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">te</p>');
  606. ua.checkSameHtml(ua.getHTML(r.startContainer), '<div id="test"><p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">a</td></tr></tbody></table><p id=\"last\">xtabc<span>span</span></p></div>');
  607. ua.checkResult(r, div, div, 4, 4, true, 'startContainer--补全前面的标签');
  608. });
  609. /*startContainer和endContainer为文本节点,为兄弟节点*/
  610. test('extractContents--切的部分为兄弟节点', function () {
  611. var div = te.dom[2];
  612. var r = new baidu.editor.dom.Range(document);
  613. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  614. var first = document.getElementById('first');
  615. r.setStart(first.firstChild, 1).setEnd(first.lastChild, 4);
  616. /*strong前面有空格*/
  617. ua.checkSameHtml(ua.getHTML(r.extractContents()), 'irst<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> str');
  618. ua.checkSameHtml(ua.getHTML(r.startContainer), '<p id=\"first\">fong.</p>', 'check startContainer html');
  619. ua.checkResult(r, first, first, 1, 1, true, 'startContainer--startContainer和endContainer为兄弟节点');
  620. });
  621. test('extractContents--切同一个文本节点', function () {
  622. var div = te.dom[2];
  623. var r = new baidu.editor.dom.Range(document);
  624. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  625. var first = document.getElementById('first').firstChild;
  626. r.setStart(first, 1).setEnd(first, 4);
  627. equals(ua.getHTML(r.extractContents()), 'irs');
  628. equal(ua.getHTML(r.startContainer), 'ft');
  629. ua.checkResult(r, first, first, 1, 1, true, 'startContainer--切同一个文本节点');
  630. });
  631. /*startContainer和endContainer的nodeType=1*/
  632. test('extractContents--startContainer和endContainer为非文本节点', function () {
  633. var div = te.dom[2];
  634. var r = new baidu.editor.dom.Range(document);
  635. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  636. var first = document.getElementById('first');
  637. var last = document.getElementById('last');
  638. r.setStart(first, 0).setEnd(last, 0);
  639. ua.checkSameHtml(ua.getHTML(r.extractContents()), '<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b><em>em text</em>more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\"></p>');
  640. ua.checkSameHtml(ua.getHTML(r.startContainer), '<div id="test"><p id=\"first\"></p><p id=\"last\">textabc<span>span</span></p></div>');
  641. ua.checkResult(r, div, div, 1, 1, true, 'cloneContents--开始和结束位置都是文本');
  642. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  643. first = document.getElementById('first');
  644. last = document.getElementById('last');
  645. r.setStart(first, 2).setEnd(last, 1);
  646. ua.checkSameHtml(ua.getHTML(r.extractContents()), '<p id="first"> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b><em>em text</em>more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc</p>', '检查得到的contents');
  647. ua.checkSameHtml(ua.getHTML(r.startContainer), '<div id="test"><p id=\"first\">first<!--not--></p><p id=\"last\"><span>span</span></p></div>', '检查切除后');
  648. ua.checkResult(r, div, div, 1, 1, true, 'extractContents--开始位置有注释');
  649. });
  650. test('extractContents--完整切掉一个节点', function () {
  651. var div = te.dom[2];
  652. var r = new baidu.editor.dom.Range(document);
  653. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  654. var first = document.getElementById('first');
  655. r.setStart(div, 0).setEnd(div, div.childNodes.length - 1);
  656. ua.checkSameHtml(ua.getHTML(r.extractContents()), '<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b><em>em text</em>more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table>');
  657. ua.checkSameHtml(ua.getHTML(r.startContainer), '<div id="test"><p id=\"last\">textabc<span>span</span></p></div>');
  658. ua.checkResult(r, div, div, 0, 0, true, 'extractContents--完整切掉一个节点');
  659. });
  660. test('extractContents--元素闭合', function () {
  661. var div = te.dom[2];
  662. var range = new baidu.editor.dom.Range(document);
  663. div.innerHTML = '<p>p_text</p>';
  664. var text = div.firstChild.firstChild;
  665. range.setStart(text, 1).setEnd(text, 1);
  666. equals(ua.getHTML(range.extractContents()), 'null', '元素闭合直接返回null');
  667. equal(ua.getHTML(range.startContainer), 'p_text');
  668. ua.checkResult(range, text, text, 1, 1, true, 'extractContents--startContainer的nodeType=1,endContainer为em');
  669. var p = div.firstChild;
  670. range.setStart(p, 1).setEnd(p, 1);
  671. equals(ua.getHTML(range.extractContents()), 'null', '元素闭合直接返回null');
  672. equal(ua.getHTML(range.startContainer), '<p>p_text</p>');
  673. ua.checkResult(range, p, p, 1, 1, true, 'extractContents--startContainer的nodeType=1,endContainer为em');
  674. });
  675. test('extractContents--自闭合元素', function () {
  676. var div = te.dom[2];
  677. var range = new baidu.editor.dom.Range(document);
  678. var inner = '<b>b_text<i id="ii">i_text</i><img /></b>xxx';
  679. div.innerHTML = inner;
  680. var b = div.firstChild;
  681. div.innerHTML = inner;
  682. b = div.firstChild;
  683. range.setStart(b.firstChild, 2).setEnd(b, b.childNodes.length);
  684. /*只能获得<img>而不是<img />的标签*/
  685. equal(ua.getHTML(range.extractContents()), 'text<i id="ii">i_text</i><img>', '获取带有<img>的内容');
  686. equal(ua.getHTML(range.startContainer), '<b>b_</b>', '检查切除元素后');
  687. ua.checkResult(range, b, b, 1, 1, true, '选中结束位置为自闭合元素');
  688. });
  689. test('extractContents', function () {
  690. function trans(range) {
  691. return {
  692. startContainer:range.startContainer.id,
  693. startOffset:range.startOffset,
  694. endContainer:range.endContainer.id,
  695. endOffset:range.endOffset
  696. };
  697. }
  698. var div = te.dom[2];
  699. var range = new baidu.editor.dom.Range(document);
  700. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  701. var r = range;
  702. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  703. r.setStart(document.getElementById('test'), 0);
  704. r.setEnd(document.getElementById('traverse'), 2);
  705. ua.checkSameHtml(ua.getHTML(r.extractContents()), '<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em">some text</em></b><em>em text</em></p>');
  706. ua.checkSameHtml(ua.getHTML(r.startContainer), '<div id="test"><p id="traverse">more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
  707. equals(r.startOffset, 0);
  708. equals(r.endContainer.nodeType, 1);
  709. equals(r.endOffset, 0);
  710. ua.checkSameHtml(ua.getHTML(r.endContainer), '<div id="test"><p id="traverse">more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
  711. ua.checkSameHtml(ua.getHTML(document.getElementById('test')), '<div id="test"><p id="traverse">more text</p><table id="table" width="300"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
  712. equals(r.collapsed, true);
  713. });
  714. /*只要邻居节点不是块元素就左扩或右扩*/
  715. test('enlarge--文本节点左边扩到body', function () {
  716. var div = te.dom[2];
  717. var range = new baidu.editor.dom.Range(document);
  718. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<div>div_text</div></p>';
  719. var first = document.getElementById('first').firstChild;
  720. var last = document.getElementById('last').firstChild;
  721. range.setStart(first, 1).setEnd(last, 2);
  722. range.enlarge(true);
  723. /*左边的文本节点是左边第一个节点,所以一直左扩直到body,右边的文本节点右边有兄弟,因此只扩到第一个块元素祖先*/
  724. ua.checkResult(range, document.body, div, ua.getIndex(div), 5, false, '左边扩到body');
  725. });
  726. test('enlarge--文本节点右边扩到body', function () {
  727. var div = te.dom[2];
  728. var range = new baidu.editor.dom.Range(document);
  729. div.innerHTML = '<div id=\"first\"><p>xxx</p>first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</div><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  730. var strong = document.getElementById('strong').firstChild;
  731. var span = document.getElementById('last').lastChild.firstChild;
  732. range.setStart(strong, 1).setEnd(span, 2);
  733. range.enlarge(true);
  734. /*右边的文本节点是右边最后一个节点,所以一直右扩直到body,左边的文本节点左边边有块元素兄弟,因此只扩到第一个块元素祖先*/
  735. ua.checkResult(range, div.firstChild, document.body, 1, ua.getIndex(div) + 1, false, '右边扩到body');
  736. });
  737. test('enlarge--文本节点左右边扩到body', function () {
  738. var div = te.dom[2];
  739. var range = new baidu.editor.dom.Range(document);
  740. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  741. var first = document.getElementById('first').firstChild;
  742. var span = document.getElementById('last').lastChild.firstChild;
  743. range.setStart(first, 1).setEnd(span, 2);
  744. range.enlarge(true);
  745. /*右边的文本节点是右边最后一个节点,所以一直右扩直到body,左边的文本节点是左边第一个节点,所以一直左扩直到body*/
  746. ua.checkResult(range, document.body, document.body, ua.getIndex(div), ua.getIndex(div) + 1, false, '左右边扩到body');
  747. });
  748. test('enlarge--startContainer和endContainer的nodeType为1', function () {
  749. var div = te.dom[2];
  750. var range = new baidu.editor.dom.Range(document);
  751. div.innerHTML = '<p id=\"first\">first<!--not--> strong<strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  752. range.setStart(div, 0).setEnd(div, 2);
  753. range.enlarge(true);
  754. ua.checkResult(range, document.body, div, ua.getIndex(div), 2, false, '左边扩到块元素父节点,右边扩到body');
  755. });
  756. test('enlarge--左边非块元素节点', function () {
  757. var div = te.dom[2];
  758. var range = new baidu.editor.dom.Range(document);
  759. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  760. var strong = document.getElementById('strong');
  761. var table = div.getElementsByTagName('table')[0];
  762. range.setStart(strong, 0).setEnd(table, 1);
  763. range.enlarge(true);
  764. ua.checkResult(range, document.body, div, ua.getIndex(div), 4, false, '左边扩到块元素父节点,右边扩到父节点');
  765. });
  766. test('enlarge--左右属于同一非块元素节点', function () {
  767. var div = te.dom[2];
  768. var range = new baidu.editor.dom.Range(document);
  769. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  770. var strong = document.getElementById('strong');
  771. range.setStart(strong, 0).setEnd(strong, 1);
  772. range.enlarge(true);
  773. ua.checkResult(range, document.body, div, ua.getIndex(div), 1, false, '左边扩到body');
  774. /*文本节点*/
  775. var strong_text = strong.firstChild;
  776. range.setStart(strong_text, 2).setEnd(strong_text, 3);
  777. range.enlarge(true);
  778. ua.checkResult(range, document.body, div, ua.getIndex(div), 1, false, '左右均扩到第一个块元素祖先节点');
  779. });
  780. test('enlarge--isBlock为null', function () {
  781. var div = te.dom[2];
  782. var range = new baidu.editor.dom.Range(document);
  783. div.innerHTML = 'xx<b><i>xxxx</i>xxxxxxx</b>';
  784. range.selectNodeContents(div.getElementsByTagName('i')[0]);
  785. range.enlarge();
  786. ua.checkResult(range, div, div.lastChild, 1, 1, false, 'isBlock为null');
  787. });
  788. test('enlarge--stopFn', function () {
  789. var div = te.dom[2];
  790. var stopFn = function (container) {
  791. if (container.tagName.toLowerCase() == 'table')
  792. return true;
  793. return false;
  794. };
  795. var range = new baidu.editor.dom.Range(document);
  796. div.innerHTML = '<p id=\"first\">first<!--not--> strong <!-- --><strong id=\"strong\">strong</strong> second <em id=\"em\">em</em> strong.</p><p id=\"second\">bar</p><p id=\"traverse\"><b><em id=\"em\">some text</em></b><em>em text</em>more text</p><table id=\"table\" width=\"300\"><tbody><tr><td>1</td><td id=\"two\">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\">textabc<span>span</span></p>';
  797. var strong = document.getElementById('strong');
  798. var table = div.getElementsByTagName('table')[0];
  799. range.setStart(strong, 0).setEnd(table, 1);
  800. range.enlarge(true, stopFn);
  801. ua.checkResult(range, document.body, table, ua.getIndex(div), 1, false, '左边扩到块元素父节点,右边不扩(stopFn为false)');
  802. });
  803. //test( 'enlarge--闭合特殊情况,有歧义', function() {
  804. // var div = te.dom[2];
  805. // var range = new baidu.editor.dom.Range( document );
  806. // div.innerHTML = '<p>p_text</p>';
  807. // var p = div.firstChild;
  808. // range.setStart( p.firstChild, 0 ).setEnd( p.firstChild, 3 ).trimBoundary();
  809. // range.setStart( p, 1 ).setEnd( p, 1 );
  810. // range.enlarge( true );
  811. //
  812. // //TODO
  813. //} );
  814. test('enlarge--闭合', function () {
  815. var div = te.dom[2];
  816. var range = new baidu.editor.dom.Range(document);
  817. div.innerHTML = 'xxx<p>xxxxx</p>xxx<em>xxx</em>xxxxxxx<b>xxxx|xxx</b><p>bbbbb</p>xx';
  818. range.setStart(div.getElementsByTagName('b')[0], 2).collapse(true);
  819. range.enlarge(true);
  820. ua.checkResult(range, div, div, 2, 6, false, "初始为闭合,文本父节点为非块元素");
  821. div.innerHTML = '<div></div>xxxx<div></div>';
  822. range.setStart(div.firstChild.nextSibling, 2).collapse(true)
  823. range.enlarge(true);
  824. ua.checkResult(range, div, div, 1, 2, false, "初始为闭合,文本父节点为块元素");
  825. });
  826. test('insertNode--文本中插入', function () {
  827. var div = te.dom[2];
  828. var range = new baidu.editor.dom.Range(document);
  829. div.innerHTML = 'div_text1<p>p_text</p>xxx<em>em_text</em>xxxxxxx<b>xxxx|xxx</b><p>bbbbb</p>text2_div';
  830. var p_text = div.firstChild.nextSibling.firstChild;
  831. range.setStart(p_text, 1).setEnd(p_text, 2);
  832. /*插入块元素*/
  833. var new_div = document.createElement('div');
  834. range.insertNode(new_div);
  835. ua.checkResult(range, p_text.parentNode, new_div.nextSibling, 1, 1, false, '插入div');
  836. /*插入文本节点,原来闭合*/
  837. var em_text = div.getElementsByTagName('em')[0].firstChild;
  838. range.setStart(em_text, 0).setEnd(em_text, 0);
  839. range.insertNode(document.createTextNode('new_text'));
  840. ua.checkResult(range, em_text.parentNode, em_text.parentNode, 0, 1, false, '闭合情况下插入文本');
  841. /*插入inline元素*/
  842. range.setStart(div.firstChild, 1).setEnd(div.lastChild, 1);
  843. range.insertNode(document.createElement('i'));
  844. ua.checkResult(range, div, div.lastChild, 1, 1, false, '插入inline元素');
  845. });
  846. test('inserNode--块元素中插入', function () {
  847. var div = te.dom[2];
  848. var range = new baidu.editor.dom.Range(document);
  849. div.innerHTML = 'div_text1<p>p_text</p>xxx<em>em_text</em>xxxxxxx<b>xxxx|xxx</b><p>bbbbb</p>text2_div';
  850. // var p_text = div.firstChild.nextSibling.firstChild;
  851. range.setStart(div, 1).setEnd(div.lastChild, 2);
  852. /*插入块元素*/
  853. var new_div = document.createElement('div');
  854. range.insertNode(new_div);
  855. ua.checkResult(range, div, div.lastChild, 1, 2, false, '插入div');
  856. });
  857. test('insertNode--插入的节点为endContainer孩子', function () {
  858. var div = te.dom[2];
  859. var range = new baidu.editor.dom.Range(document);
  860. div.innerHTML = 'xxx<p>xxxxx</p>xxx<em>xxx</em>xxxxxxx<b>xxxx|xxx</b><p>bbbbb</p>xx';
  861. var length = div.childNodes.length;
  862. range.setStart(div, 1).setEnd(div, length);
  863. var new_div = document.createElement('div');
  864. new_div.innerHTML = 'xxxx<div>div_text<span></span></div><i>i_text</i><img /><em>em_text</em>xxxx';
  865. range.insertNode(new_div);
  866. ua.checkResult(range, div, div, 1, length + 1, false, '插入节点为endContainer的孩子');
  867. equal(ua.getHTML(div), '<div id="test">xxx<div>xxxx<div>div_text<span></span></div><i>i_text</i><img><em>em_text</em>xxxx</div><p>xxxxx</p>xxx<em>xxx</em>xxxxxxx<b>xxxx|xxx</b><p>bbbbb</p>xx</div>')
  868. });
  869. test('insertNode--插入的fragment为endContainer孩子', function () {
  870. var div = te.dom[2];
  871. var range = new baidu.editor.dom.Range(document);
  872. var frag = document.createDocumentFragment();
  873. div.innerHTML = 'xxx<p>xxxxx</p>xxx<em>xxx</em>xxxxxxx<b>xxxx|xxx</b><p>bbbbb</p>xx';
  874. var length = div.childNodes.length;
  875. range.setStart(div, 1).setEnd(div, div.childNodes.length);
  876. var new_div = document.createElement('div');
  877. frag.appendChild(new_div);
  878. frag.appendChild(document.createTextNode('text'));
  879. frag.appendChild(document.createElement('span'));
  880. range.insertNode(frag);
  881. ua.checkResult(range, div, div, 1, length + 3, false, '插入fragment为endContainer的孩子');
  882. equal(ua.getHTML(div), '<div id="test">xxx<div></div>text<span></span><p>xxxxx</p>xxx<em>xxx</em>xxxxxxx<b>xxxx|xxx</b><p>bbbbb</p>xx</div>', '比较innerHTML');
  883. });
  884. test('createBookmark/moveToBookmark--元素不闭合', function () {
  885. var div = te.dom[2];
  886. var range = new baidu.editor.dom.Range(document);
  887. div.innerHTML = 'first_text<b><i>i_text</i>xxxxxxx</b><span id="span">span_text</span><p id="second"><em>em_text</em>p_text</p>';
  888. var bookmark = range.selectNode(div).createBookmark();
  889. ua.checkResult(range, document.body, document.body, ua.getIndex(div), ua.getIndex(div) + 1, false, "元素不闭合,创建书签");
  890. ok(/_baidu_bookmark_start_/.test(div.previousSibling.id), '检查div的前一个兄弟');
  891. ok(/_baidu_bookmark_end_/.test(div.nextSibling.id), '检查div的后一个兄弟');
  892. /*moveToBookmark*/
  893. range.moveToBookmark(bookmark);
  894. ua.checkResult(range, document.body, document.body, ua.getIndex(div), ua.getIndex(div) + 1, false, "元素不闭合,删除书签");
  895. ok(!/_baidu_bookmark_start_/.test(div.previousSibling.id), '检查div的前面书签是否被删除');
  896. range.setStart(div, 2).setEnd(div, 3);
  897. var bookmark = range.createBookmark(true);
  898. ua.checkResult(range, div, div, 3, 4, false, "元素不闭合,插入span");
  899. var preId = document.getElementById('span').previousSibling.id;
  900. var latterId = document.getElementById('span').nextSibling.id;
  901. var reg = /_baidu_bookmark_start_/;
  902. ok(/_baidu_bookmark_start_/.test(preId), '检查前面span的id');
  903. ok(/_baidu_bookmark_end_/.test(latterId), '检查后面span的id');
  904. checkBookmark(bookmark, preId, latterId, true);
  905. range.moveToBookmark(bookmark);
  906. ua.checkResult(range, div, div, 2, 3, false, 'moveToBookmark');
  907. equal(ua.getHTML(div), '<div id="test">first_text<b><i>i_text</i>xxxxxxx</b><span id="span">span_text</span><p id="second"><em>em_text</em>p_text</p></div>');
  908. });
  909. test('createBookmark/moveToBookmark--span嵌套', function () {
  910. var div = te.dom[2];
  911. var range = new baidu.editor.dom.Range(document);
  912. div.innerHTML = 'first_text<b><i>i_text</i>xxxxxxx</b><span id="span">span_text</span><p id="second"><em>em_text</em>p_text</p>';
  913. var span = document.getElementById('span');
  914. range.setStart(span, 0).setEnd(span, 1);
  915. var bookmark = range.createBookmark();
  916. var pre = span.firstChild;
  917. var latter = span.lastChild;
  918. ua.checkResult(range, span, span, 1, 2, false, 'span嵌套');
  919. ok(/_baidu_bookmark_start_/.test(pre.id), '检查前面span的id');
  920. ok(/_baidu_bookmark_end_/.test(latter.id), '检查后面span的id');
  921. checkBookmark(bookmark, pre, latter, undefined);
  922. });
  923. test('createBookmark/moveToBookmark--元素闭合', function () {
  924. var div = te.dom[2];
  925. var range = new baidu.editor.dom.Range(document);
  926. div.innerHTML = 'first_text<b><i>i_text</i>xxxxxxx</b><span id="span">span_text</span><p id="second"><em id="em">em_text</em>p_text</p>';
  927. var em_text = document.getElementById('em').firstChild;
  928. var em = em_text.parentNode;
  929. range.setStart(em_text, 1).setEnd(em_text, 1);
  930. var bookmark = range.createBookmark(true, true);
  931. ua.checkResult(range, em, em, 2, 2, true, '元素闭合');
  932. var pre = em.firstChild.nextSibling;
  933. checkBookmark(bookmark, pre.id, null, true);
  934. equal('_baidu_bookmark_start_', pre.id, '检查前面span的id');
  935. });
  936. test('getClosedNode', function () {
  937. var div = te.dom[2];
  938. var range = new baidu.editor.dom.Range(document);
  939. div.innerHTML = 'xxx<span>xxx</span><img />xxxx';
  940. range.setStart(div, 2).setEnd(div, 3);
  941. same(range.getClosedNode(), div.lastChild.previousSibling, 'check result is img');
  942. range.setStart(div, 2).collapse(true);
  943. equal(range.getClosedNode(), null, 'check null return result');
  944. range.setStart(div, 0).setEnd(div, 1);
  945. equal(range.getClosedNode(), null, 'get null result');
  946. });
  947. test('applyInlineStyle--strong', function () {
  948. var div = te.dom[2];
  949. var range = new baidu.editor.dom.Range(document);
  950. div.innerHTML = 'div_text';
  951. range.setStart(div, 0).setEnd(div, 1);
  952. range.applyInlineStyle('strong');
  953. equals(ua.getHTML(div), '<div id="test"><strong>div_text</strong></div>');
  954. });
  955. test('applyInlineStyle--双重strong', function () {
  956. var div = te.dom[2];
  957. var range = new baidu.editor.dom.Range(document);
  958. div.innerHTML = 'div_text';
  959. div.innerHTML = 'div_text<strong>strong_text</strong>';
  960. range.setStart(div.firstChild, 3);
  961. range.setEnd(div.firstChild.nextSibling.firstChild, 3);
  962. range.applyInlineStyle('strong');
  963. equals(ua.getHTML(div), '<div id="test">div<strong>_textstrong_text</strong></div>', '同一个块元素父标签双重加粗');
  964. div.innerHTML = 'xx<p>xx<strong>bbbb</strong>xxx</p>xx<p><strong>aaaaaaa</strong></p>';
  965. range.setStartBefore(div.firstChild.nextSibling.firstChild);
  966. range.setEndAfter(div.lastChild.firstChild.firstChild);
  967. range.applyInlineStyle('strong');
  968. equals(ua.getHTML(div), '<div id="test">xx<p><strong>xxbbbbxxx</strong></p><strong>xx</strong><p><strong>aaaaaaa</strong></p></div>', '跨块元素的加粗');
  969. });
  970. test('applyInlineStyle--span放在em外面', function () {
  971. var div = te.dom[2];
  972. var range = new baidu.editor.dom.Range(document);
  973. div.innerHTML = '<div><em>div_text</em></div>';
  974. range.setStart(div, 0).setEnd(div, 1);
  975. range.applyInlineStyle('span', {style:'font-size:12px'});
  976. var span = div.firstChild.firstChild;
  977. equal($(span.firstChild).css('font-size'), '12px', 'check style');
  978. });
  979. test('applyInlineStyle--span', function () {
  980. var div = te.dom[2];
  981. var range = new baidu.editor.dom.Range(document);
  982. div.innerHTML = 'div_text';
  983. range.setStart(div, 0).setEnd(div, 1);
  984. range.applyInlineStyle('span', {style:'font-size:12px'});
  985. var span = div.firstChild;
  986. equal($(span).css('font-size'), '12px', 'check style');
  987. equal(span.firstChild.data, 'div_text', 'check innerHTML');
  988. });
  989. test('applyInlineStyle--span元素闭合', function () {
  990. var div = te.dom[2];
  991. var range = new baidu.editor.dom.Range(document);
  992. div.innerHTML = 'div_text';
  993. range.setStart(div, 0).setEnd(div, 0);
  994. range.applyInlineStyle('span', {style:'font-size:12px'});
  995. equal(ua.getHTML(div), '<div id="test">div_text</div>');
  996. });
  997. //TODO
  998. test('applyInlineStyle-双重span', function () {
  999. var div = te.dom[2];
  1000. var range = new baidu.editor.dom.Range(document);
  1001. div.innerHTML = '<span style="font-size:12px">div_text</span>';
  1002. var span = div.firstChild;
  1003. range.setStart(span.firstChild, 0).setEnd(span.firstChild, 4);
  1004. range.applyInlineStyle('span', {style:'color:red'});
  1005. var div_new = document.createElement('div');
  1006. div_new.id = 'test';
  1007. //1.2.6.1开启span套 span,调整
  1008. // div_new.innerHTML = '<span style="font-size: 12px"><span style="color: red; font-size: 12px">div_</span>text</span>';
  1009. div_new.innerHTML = '<span style="font-size: 12px; color: red;">div_</span><span style="font-size:12px">text</span>';
  1010. ok(ua.haveSameAllChildAttribs(div, div_new), 'check style');
  1011. });
  1012. test('applyInlineStyle--b', function () {
  1013. var div = te.dom[2];
  1014. var range = new baidu.editor.dom.Range(document);
  1015. div.innerHTML = '<ul><li>li_text</li><li>bbbb</li></ul>';
  1016. var li_text = div.firstChild.firstChild;
  1017. range.setStart(li_text, 0).setEnd(div, 1);
  1018. range.applyInlineStyle('b');
  1019. equals(ua.getHTML(div), '<div id="test"><ul><li><b>li_text</b></li><li><b>bbbb</b></li></ul></div>');
  1020. div.innerHTML = '<ul><li>li_text</li><li>bbbb</li></ul>';
  1021. li_text = div.firstChild.firstChild.firstChild;
  1022. range.setStart(li_text, 1).setEnd(li_text, 3);
  1023. range.applyInlineStyle('b');
  1024. equal(ua.getHTML(div), '<div id="test"><ul><li>l<b>i_</b>text</li><li>bbbb</li></ul></div>');
  1025. });
  1026. test('applyInlineStyle-b元素闭合', function () {
  1027. var div = te.dom[2];
  1028. var range = new baidu.editor.dom.Range(document);
  1029. div.innerHTML = '<ul><li>li_text</li><li>bbbb</li></ul>';
  1030. var li_text = div.firstChild.firstChild;
  1031. range.setStart(li_text, 1).setEnd(li_text, 1);
  1032. range.applyInlineStyle('b');
  1033. equals(ua.getHTML(div), '<div id="test"><ul><li>li_text</li><li>bbbb</li></ul></div>');
  1034. });
  1035. test('applyInlineStyle-b有属性', function () {
  1036. var div = te.dom[2];
  1037. var range = new baidu.editor.dom.Range(document);
  1038. div.innerHTML = '<p>1234</p>';
  1039. range.setStart(div, 0).setEnd(div.firstChild, 4);
  1040. range.applyInlineStyle('b', {title:'b_title', id:'b_id'});
  1041. var b = div.firstChild.firstChild;
  1042. same(b, document.getElementById('b_id'), '插入带有属性的b');
  1043. equal($(b).attr('title'), 'b_title', 'check title');
  1044. equal(b.innerHTML, '1234', 'check innerHTML');
  1045. equal(div.childNodes.length, 1, 'check child count');
  1046. });
  1047. test('applyInlineStyle--b放在Inline元素外面', function () {
  1048. var div = te.dom[2];
  1049. var range = new baidu.editor.dom.Range(document);
  1050. div.innerHTML = '<p><em>1234</em>5678<span>9</span></p><p><em>1234</em>5678<span>9</span></p>';
  1051. range.setStart(div, 0).setEnd(div, 2);
  1052. range.applyInlineStyle('b');
  1053. equals(ua.getHTML(div), '<div id="test"><p><b><em>1234</em>5678<span>9</span></b></p><p><b><em>1234</em>5678<span>9</span></b></p></div>', 'Inline element on multiple selected elements with various childnodes');
  1054. div.innerHTML = '<p>x<em><span id="span">1234</span></em>y</p>';
  1055. var span = document.getElementById('span');
  1056. range.setStart(span.firstChild, 0).setEnd(span.firstChild, 4);
  1057. range.applyInlineStyle('b');
  1058. equals(ua.getHTML(div), '<div id="test"><p>x<b><em><span id="span">1234</span></em></b>y</p></div>', '多个嵌套Inline element');
  1059. });
  1060. test('applyInlinestyle--b没有文字', function () {
  1061. var div = te.dom[2];
  1062. var range = new baidu.editor.dom.Range(document);
  1063. div.innerHTML = '<table><tr><td><br/></td></tr><tr><td><br/></td></tr><tr><td><br/></td></tr></table>';
  1064. range.setStart(div, 0).setEnd(div, 1);
  1065. range.applyInlineStyle('b');
  1066. equals(ua.getHTML(div), '<div id="test"><table><tbody><tr><td><br></td></tr><tr><td><br></td></tr><tr><td><br></td></tr></tbody></table></div>', '空表格');
  1067. ua.checkResult(range, div, div, 0, 1, false, '对空表格进行b');
  1068. //todo ie6下不知道为啥strong用不上去
  1069. // div.innerHTML = '';
  1070. // var ie6 = (baidu.editor.browser.ie == 6);
  1071. // if ( ie6 ) {
  1072. // div.appendChild( document.createTextNode( '\u200B' ) );
  1073. // div.appendChild( document.createTextNode( '\u200B' ) );
  1074. // }
  1075. // else {
  1076. // div.appendChild( document.createTextNode( '\ufeff' ) );
  1077. // div.appendChild( document.createTextNode( '\ufeff' ) );
  1078. // }
  1079. // range.setStart(div,0).setEnd( div, 1 );
  1080. // range.applyInlineStyle( 'strong' );
  1081. // equals( div.getElementsByTagName( 'strong' ).length, 1 );
  1082. // if ( ie6 )
  1083. // equal( div.innerHTML.toLowerCase(), '<strong>\u200B</strong>\u200B', 'div has no text' );
  1084. // else
  1085. // equal( div.innerHTML.toLowerCase(), '<strong>\ufeff</strong>\ufeff', 'div has no text' );
  1086. });
  1087. test('applyInlineStyle-双重b', function () {
  1088. var div = te.dom[2];
  1089. var range = new baidu.editor.dom.Range(document);
  1090. div.innerHTML = '<p><b>b_text</b></p>';
  1091. var b_text = div.firstChild.firstChild.firstChild;
  1092. range.setStart(b_text, 1).setEnd(b_text, 2);
  1093. range.applyInlineStyle('b');
  1094. equals(div.innerHTML.toLowerCase(), '<p><b>b_text</b></p>', '文本双重b');
  1095. div.innerHTML = '<p><b>a<em>1234</em>b</b></p>';
  1096. range.setStart(div.getElementsByTagName('em')[0].firstChild, 0);
  1097. range.setEnd(div.getElementsByTagName('em')[0].firstChild, 4);
  1098. range.applyInlineStyle('b');
  1099. equals(div.innerHTML.toLowerCase(), '<p><b>a<em>1234</em>b</b></p>', '双重b+多个inline元素');
  1100. // Inline element merged with parent and child
  1101. div.innerHTML = '<p>a<b>12<b>34</b>56</b>b</p>';
  1102. range.setStart(div.getElementsByTagName('b')[0].firstChild, 1);
  1103. range.setEnd(div.getElementsByTagName('b')[0].lastChild, 1);
  1104. range.applyInlineStyle('b');
  1105. equals(div.innerHTML.toLowerCase(), '<p>a<b>123456</b>b</p>', '去掉嵌套的b');
  1106. });
  1107. test('applyInlineStyle--多个style', function () {
  1108. var div = te.dom[2];
  1109. var range = new baidu.editor.dom.Range(document);
  1110. div.innerHTML = 'xxxx';
  1111. range.setStart(div, 0).setEnd(div, 1);
  1112. range.applyInlineStyle('i').applyInlineStyle('span', {style:'color:red'}).applyInlineStyle('span', {style:'font-size:12px'});
  1113. //1.2.6.1 span能套i
  1114. // var span = div.firstChild.firstChild;
  1115. var span = div.firstChild;
  1116. equal(span.style['color'], 'red', 'check color');
  1117. equal($(span).css('font-size'), '12px', 'check font size');
  1118. //1.2.6.1 span能套i
  1119. equal(span.innerHTML.toLowerCase(), '<i>xxxx</i>', 'check innerHTML including u');
  1120. });
  1121. test('applyInlineStyle--MergeToParent', function () {
  1122. var div = te.dom[2];
  1123. var range = new baidu.editor.dom.Range(document);
  1124. div.innerHTML = '1<strong style="font-size: 24px; ">23456</strong>8910';
  1125. range.setStart(div.firstChild, 0).setEnd(div.childNodes[1], 1).select();
  1126. range.applyInlineStyle('strong', {style:'font-size:24px'});
  1127. var html = '<strong style="font-size: 24px;">123456</strong>8910';
  1128. ua.checkSameHtml(div.innerHTML, html);
  1129. });
  1130. test('trace1583:applyInlineStyle--MergeToChild', function () {
  1131. var div = te.dom[2];
  1132. var range = new baidu.editor.dom.Range(document);
  1133. div.innerHTML = '<span style="font-size: 24px; ">​123<span style="font-size: 16px; ">45678</span>9</span>';
  1134. var span = div.getElementsByTagName('span')[1];
  1135. range.setStart(span.firstChild, 2).setEnd(span.firstChild, 4).select();
  1136. range.applyInlineStyle('span', {style:'font-size:24px'});
  1137. var html = '<span style="font-size:24px">123<span style="font-size:16px">45<span style="font-size: 24px; ">67</span>8</span>9</span>';
  1138. ua.checkHTMLSameStyle(html, document, div, 'MergeToChild');
  1139. });
  1140. test('applyInlineStyle--选区包含部分兄弟', function () {
  1141. var div = te.dom[2];
  1142. var range = new baidu.editor.dom.Range(document);
  1143. div.innerHTML = 'xxxx<span>span_text</span>';
  1144. range.setStart(div, 0).setEnd(div.firstChild.nextSibling, 0);
  1145. range.applyInlineStyle('u');
  1146. equal(div.innerHTML.toLowerCase(), '<u>xxxx</u><span>span_text</span>', 'check innerHTML including u');
  1147. });
  1148. test('removeInlineStyle--删除父节点b', function () {
  1149. var div = te.dom[2];
  1150. var range = new baidu.editor.dom.Range(document);
  1151. div.innerHTML = '<b>xxxx</b>';
  1152. range.setStart(div, 0).setEnd(div, 1);
  1153. range.removeInlineStyle('b');
  1154. equals(div.innerHTML, 'xxxx', '删除b');
  1155. });
  1156. test('removeInlineStyle--删除祖先b', function () {
  1157. var div = te.dom[2];
  1158. var range = new baidu.editor.dom.Range(document);
  1159. div.innerHTML = "<b><i>xxxx</i></b>";
  1160. var i = div.firstChild.firstChild;
  1161. range.setStart(i, 0).setEnd(i, 1);
  1162. range.removeInlineStyle('b');
  1163. equals(div.innerHTML.toLowerCase(), '<i>xxxx</i>');
  1164. ua.checkResult(range, div, div, 0, 1, false, '删除祖先b');
  1165. });
  1166. test('removeInlineStyle--删除部分b', function () {
  1167. var div = te.dom[2];
  1168. var range = new baidu.editor.dom.Range(document);
  1169. div.innerHTML = "<b><i>i_text</i></b><span>span_text</span>";
  1170. var b = div.firstChild;
  1171. range.setStart(b, 0).setEnd(b.firstChild.firstChild, 3);
  1172. range.removeInlineStyle('b');
  1173. equals(div.innerHTML.toLowerCase(), '<i>i_t</i><b><i>ext</i></b><span>span_text</span>', '检查html');
  1174. ua.checkResult(range, div, div, 0, 1, false, '删除部分b');
  1175. });
  1176. test('removeInlineStyle--删除多个b', function () {
  1177. var div = te.dom[2];
  1178. var range = new baidu.editor.dom.Range(document);
  1179. div.innerHTML = "<table><tr><td>&nbsp;</td><td><table><tr><td><b>xxxxxx</b></td></tr></table></td><td><b>xxxxxx</b></td></tr></table>";
  1180. range.setStart(div, 0).setEnd(div, 1);
  1181. range.removeInlineStyle('b');
  1182. equals(ua.getHTML(div), '<div id="test"><table><tbody><tr><td>&nbsp;</td><td><table><tbody><tr><td>xxxxxx</td></tr></tbody></table></td><td>xxxxxx</td></tr></tbody></table></div>');
  1183. div.innerHTML = '<b><i>xxxxx</i></b><i>bb</i><b>bbb</b>b<b><i>ccccc</i></b>';
  1184. range.setStart(div.getElementsByTagName('b')[0], 0);
  1185. range.setEndAfter(div.getElementsByTagName('b')[2].firstChild);
  1186. range.removeInlineStyle('b');
  1187. equals(div.innerHTML.toLowerCase(), '<i>xxxxx</i><i>bb</i>bbbb<i>ccccc</i>');
  1188. });
  1189. test('removeInlineStyle--删除不同层文本的样式', function () {
  1190. var div = te.dom[2];
  1191. var range = new baidu.editor.dom.Range(document);
  1192. div.innerHTML = "xxx<b>b_text</b><span><b>b2_text</b></span>";
  1193. range.setStart(div, 0).setEnd(div, 1);
  1194. var b1 = div.firstChild.nextSibling;
  1195. var b2 = b1.nextSibling.firstChild;
  1196. range.setStart(b1.firstChild, 2).setEnd(b2.firstChild, 2);
  1197. range.removeInlineStyle('b');
  1198. equals(div.innerHTML.toLowerCase(), 'xxx<b>b_</b>text<span>b2<b>_text</b></span>');
  1199. ua.checkResult(range, div, div.lastChild, 2, 1, false, 'check startContainer等');
  1200. });
  1201. test('removeInlineStyle--删除部分文本样式,需要切分文本节点', function () {
  1202. var div = te.dom[2];
  1203. var range = new baidu.editor.dom.Range(document);
  1204. div.innerHTML = 'xxx<b><i id="i"><u>u_text</u></i></b>';
  1205. range.setStart(div.firstChild, 2).setEnd(div.getElementsByTagName('u')[0].firstChild, 2);
  1206. range.removeInlineStyle('u');
  1207. equals(ua.getHTML(div), '<div id="test">xxx<b><i id="i">u_<u>text</u></i></b></div>', 'u为父亲节点');
  1208. ua.checkResult(range, div, document.getElementById('i'), 1, 1, false, '检查startOffset等');
  1209. div.innerHTML = 'xxx<b><i><u id="u">u_text</u></i></b>';
  1210. range.setStart(div.firstChild, 2).setEnd(div.getElementsByTagName('u')[0].firstChild, 2);
  1211. range.removeInlineStyle('i');
  1212. /*不能避免产生相同id元素。。。*/
  1213. equals(ua.getHTML(div), '<div id="test">xxx<b><u id="u">u_</u><i><u id="u">text</u></i></b></div>', 'i为祖先节点');
  1214. ua.checkResult(range, div, div.getElementsByTagName('b')[0], 1, 1, false, '');
  1215. div.innerHTML = "<b><i><u>xxxx</u></i></b>bbbbb<b><i><u>xxxx</u></i></b>";
  1216. range.setStart(div.getElementsByTagName('u')[0].firstChild, 2).setEnd(div.getElementsByTagName('u')[1].firstChild, 2);
  1217. range.removeInlineStyle('u');
  1218. equals(div.innerHTML.toLowerCase(), '<b><i><u>xx</u>xx</i></b>bbbbb<b><i>xx<u>xx</u></i></b>', '开始和结束位置都有u');
  1219. div.innerHTML = "<b><i><u>xxxx</u></i></b>bbbbb<b><i><u>xxxx</u></i></b>";
  1220. range.setStart(div.getElementsByTagName('u')[0].firstChild, 2).setEnd(div.getElementsByTagName('u')[1].firstChild, 2);
  1221. range.removeInlineStyle('b');
  1222. equals(div.innerHTML.toLowerCase(), '<b><i><u>xx</u></i></b><i><u>xx</u></i>bbbbb<i><u>xx</u></i><b><i><u>xx</u></i></b>', '删除部分文本节点的祖先节点的样式');
  1223. ua.checkResult(range, div, div, 1, 4, false, '删除部分节点的祖先样式后');
  1224. });
  1225. /*闭合情况挪到basestyle中去做了,在这里不做任何处理*/
  1226. test('removeInlineStyle--删除闭合元素的样式', function () {
  1227. var div = te.dom[2];
  1228. var range = new baidu.editor.dom.Range(document);
  1229. div.innerHTML = "<b><i>b_text</i></b>";
  1230. range.setStart(div.firstChild.firstChild.firstChild, 2).collapse(true);
  1231. range.removeInlineStyle('b');
  1232. equals(div.innerHTML.toLowerCase(), '<b><i>b_text</i></b>');
  1233. });
  1234. test('b节点取range', function () {
  1235. var div = te.dom[2];
  1236. var editor = new baidu.editor.Editor({'autoFloatEnabled':false});
  1237. stop();
  1238. editor.render(div);
  1239. editor.ready(function () {
  1240. var range = new baidu.editor.dom.Range(editor.document);
  1241. editor.setContent('<p>hello<strong>hello1</strong>hello2</p>');
  1242. range.setStart(editor.body.firstChild.lastChild, 0).collapse(1).select();
  1243. range = editor.selection.getRange();
  1244. if ((ua.browser.ie &&ua.browser.ie < 9) || ua.browser.webkit)
  1245. ua.checkResult(range, editor.body.firstChild.lastChild.previousSibling, editor.body.firstChild.lastChild.previousSibling, 1, 1, true, '节点后--check range');
  1246. else if(ua.browser.ie &&ua.browser.ie > 8)
  1247. ua.checkResult(range, editor.body.firstChild, editor.body.firstChild, 3, 3, true, '节点后--check range');
  1248. else
  1249. ua.checkResult(range, editor.body.firstChild.lastChild.previousSibling, editor.body.firstChild.lastChild.previousSibling, 0, 0, true, '节点后--check range');
  1250. range.setStart(editor.body.firstChild.firstChild.nextSibling, 0).collapse(1);
  1251. range.select();
  1252. range = editor.selection.getRange();
  1253. if (ua.browser.webkit)
  1254. ua.checkResult(range, editor.body.firstChild.firstChild.nextSibling.firstChild, editor.body.firstChild.firstChild.nextSibling.firstChild, 1, 1, true, '节点内文本节点前--check range');
  1255. else if (ua.browser.ie&&ua.browser.ie < 9)
  1256. ua.checkResult(range, editor.body.firstChild.childNodes[1].childNodes[1], editor.body.firstChild.childNodes[1].childNodes[1], 0, 0, true, '节点内文本节点前--check range');
  1257. else if(ua.browser.ie &&ua.browser.ie > 8)
  1258. ua.checkResult(range, editor.body.firstChild.childNodes[1], editor.body.firstChild.childNodes[1], 1, 1, true, '节点后--check range');
  1259. else
  1260. ua.checkResult(range, editor.body.firstChild.firstChild.nextSibling.firstChild, editor.body.firstChild.firstChild.nextSibling.firstChild, 0, 0, true, '节点内文本节点前--check range');
  1261. range.setStart(editor.body.firstChild.childNodes[1], 0).collapse(1).select();
  1262. range = editor.selection.getRange();
  1263. if (ua.browser.webkit)
  1264. ua.checkResult(range, editor.body.firstChild.childNodes[1].firstChild, editor.body.firstChild.childNodes[1].firstChild, 1, 1, true, 'b节点--check range');
  1265. else if (ua.browser.ie&&ua.browser.ie < 9)
  1266. ua.checkResult(range, editor.body.firstChild.childNodes[1].childNodes[1], editor.body.firstChild.childNodes[1].childNodes[1], 0, 0, true, '节点内文本节点前--check range');
  1267. else if(ua.browser.ie &&ua.browser.ie > 8)
  1268. ua.checkResult(range, editor.body.firstChild.childNodes[1], editor.body.firstChild.childNodes[1], 1, 1, true, '节点后--check range');
  1269. else
  1270. ua.checkResult(range, editor.body.firstChild.childNodes[1].firstChild, editor.body.firstChild.childNodes[1].firstChild, 0, 0, true, 'b节点--check range');
  1271. start();
  1272. });
  1273. });
  1274. test('文本节点中间取range', function () {
  1275. var div = te.dom[2];
  1276. var editor = new baidu.editor.Editor({'autoFloatEnabled':false});
  1277. stop();
  1278. editor.render(div);
  1279. editor.ready(function () {
  1280. var range = new baidu.editor.dom.Range(editor.document);
  1281. editor.setContent('<p>hello2</p>');
  1282. range.setStart(editor.body.firstChild.firstChild, 2).collapse(1).select();
  1283. range = editor.selection.getRange();
  1284. if (ua.browser.ie&&ua.browser.ie < 9)
  1285. ua.checkResult(range, editor.body.firstChild.lastChild, editor.body.firstChild.lastChild, 0, 0, true, 'check range');
  1286. else if(ua.browser.ie &&ua.browser.ie > 8)
  1287. ua.checkResult(range, editor.body.firstChild, editor.body.firstChild, 2, 2, true, 'check range');
  1288. else
  1289. ua.checkResult(range, editor.body.firstChild.lastChild, editor.body.firstChild.lastChild, 2, 2, true, 'check range');
  1290. start();
  1291. });
  1292. });
  1293. //test( 'select--closedNode', function() {
  1294. // var div = te.dom[2];
  1295. // var range = new baidu.editor.dom.Range( document );
  1296. // div.innerHTML = 'div_text<span style="color:red">span_text</span><img />div2_text<em>em_text</em>';
  1297. //// range.setStart(div.getElementsBytagName('img'),0).setEnd(div.)
  1298. //// var span = div.firstChild.nextSibling;
  1299. //// range.setStart(span,1).setEnd(div,4);
  1300. //// range.select();
  1301. ////
  1302. //// ua.checkResult(range,span,div,1,4,false,'check range');
  1303. //// range.insertNode(document.createTextNode('aa'));
  1304. //// var selection = new baidu.editor.dom.Selection( document );
  1305. //// var nativeRange = selection.getRange();
  1306. // //TODO
  1307. //} );
  1308. test('range.createAddress,range.moveAddress', function () {
  1309. function equalRange(rngA, rngB) {
  1310. return rngA.startContainer === rngB.startContainer && rngA.startOffset === rngB.startOffset
  1311. && rngA.endContainer === rngB.endContainer && rngA.endOffset === rngB.endOffset
  1312. }
  1313. var div = te.dom[0];
  1314. var rng = new UE.dom.Range(document);
  1315. div.innerHTML = '<b>xxxx</b>';
  1316. var addr = rng.setStart(div.firstChild, 0).collapse(true).createAddress(true);
  1317. var rng1 = new UE.dom.Range(document);
  1318. rng1.moveToAddress(addr);
  1319. ok(equalRange(rng, rng1));
  1320. div.innerHTML = 'aaa';
  1321. div.appendChild(document.createTextNode('aaa'));
  1322. div.appendChild(document.createTextNode('aaa'));
  1323. addr = rng.setStart(div.lastChild, 0).setEnd(div.lastChild, div.lastChild.nodeValue.length).createAddress();
  1324. rng1.moveToAddress(addr);
  1325. ok(equalRange(rng, rng1));
  1326. addr = rng.setStart(div.lastChild, 0).setEnd(div.lastChild, div.lastChild.nodeValue.length).createAddress(false, true);
  1327. div.innerHTML = 'aaaaaabbb';
  1328. rng1.moveToAddress(addr);
  1329. equal(rng1.cloneContents().firstChild.nodeValue, 'bbb');
  1330. div.innerHTML = 'aaaaaabbb<b>sss</b>';
  1331. addr = rng.setStartAfter(div.firstChild.nextSibling.firstChild).collapse(true).createAddress(false);
  1332. rng1.moveToAddress(addr);
  1333. ok(equalRange(rng, rng1))
  1334. div.innerHTML = '';
  1335. div.appendChild(document.createTextNode(domUtils.fillChar));
  1336. div.appendChild(document.createTextNode('aaa'));
  1337. addr = rng.setStartAtLast(div).collapse(true).createAddress(false, true);
  1338. div.innerHTML = 'aaa';
  1339. rng1.moveToAddress(addr);
  1340. rng.setStartAtLast(div).collapse(true);
  1341. ok(equalRange(rng, rng1));
  1342. div.innerHTML = 'aaa<b>sss</b>';
  1343. div.appendChild(document.createTextNode(domUtils.fillChar));
  1344. addr = rng.setStartAtLast(div).collapse(true).createAddress(false, true);
  1345. div.innerHTML = 'aaa<b>sss</b>';
  1346. rng1.moveToAddress(addr);
  1347. rng.setStartAtLast(div).collapse(true);
  1348. ok(equalRange(rng, rng1));
  1349. div.innerHTML = 'aaa';
  1350. div.appendChild(document.createTextNode(domUtils.fillChar));
  1351. div.appendChild(document.createTextNode('aaa'));
  1352. //空节点有占位
  1353. addr = rng.setStart(div.firstChild.nextSibling, 0).collapse(true).createAddress(false, true);
  1354. div.innerHTML = 'aaaaaa';
  1355. rng1.moveToAddress(addr);
  1356. rng.setStart(div.firstChild, 3).collapse(true);
  1357. ok(equalRange(rng, rng1));
  1358. });
  1359. test('equals', function () {
  1360. var div = te.dom[2];
  1361. var rng = new UE.dom.Range(document);
  1362. div.innerHTML = '<b>xxxx</b>';
  1363. rng.setStart(div.firstChild, 0).collapse(true);
  1364. var rng2 = rng.cloneRange();
  1365. ok(rng.equals(rng2))
  1366. });