Bug 1123505 - Part 2: Tests. a=lmandel
authorMats Palmgren <mats@mozilla.com>
Mon, 02 Feb 2015 22:34:17 +0000
changeset 249676 7e3f344f8356bbf352055b0231caa918e8c8c060
parent 249675 5223d6e4ab501fa24a94f05c0addeb3cbe7d800c
child 249677 d79341adb336f254605e25aaeaf05e2b7cc413da
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslmandel
bugs1123505
milestone37.0a2
Bug 1123505 - Part 2: Tests. a=lmandel
dom/base/test/copypaste.js
dom/base/test/test_copypaste.html
--- a/dom/base/test/copypaste.js
+++ b/dom/base/test/copypaste.js
@@ -47,40 +47,43 @@ function testCopyPaste (isXHTML) {
 
   function copySelectionToClipboard(suppressUnicodeCheck) {
     documentViewer.copySelection();
     if (!suppressUnicodeCheck)
       ok(clipboard.hasDataMatchingFlavors(["text/unicode"], 1,1), "check text/unicode");
     if (!suppressHTMLCheck)
       ok(clipboard.hasDataMatchingFlavors(["text/html"], 1,1), "check text/html");
   }
-  function copyToClipboard(node, suppressUnicodeCheck) {
+  function clear(node, suppressUnicodeCheck) {
     textarea.blur();
     clipboard.emptyClipboard(1);
     var sel = window.getSelection();
     sel.removeAllRanges();
+  }
+  function copyToClipboard(node, suppressUnicodeCheck) {
+    clear();
     var r = document.createRange();
     r.selectNode(node);
     window.getSelection().addRange(r);
     copySelectionToClipboard(suppressUnicodeCheck);
   }
-  function copyRangeToClipboard(startNode,startIndex,endNode,endIndex,suppressUnicodeCheck) {
-    textarea.blur();
-    clipboard.emptyClipboard(1);
+  function addRange(startNode,startIndex,endNode,endIndex) {
     var sel = window.getSelection();
-    sel.removeAllRanges();
     var r = document.createRange();
     r.setStart(startNode,startIndex)
     r.setEnd(endNode,endIndex)
-    window.getSelection().addRange(r);
+    sel.addRange(r);
+  }
+  function copyRangeToClipboard(startNode,startIndex,endNode,endIndex,suppressUnicodeCheck) {
+    clear();
+    addRange(startNode,startIndex,endNode,endIndex);
     copySelectionToClipboard(suppressUnicodeCheck);
   }
   function copyChildrenToClipboard(id) {
-    textarea.blur();
-    clipboard.emptyClipboard(1);
+    clear();
     window.getSelection().selectAllChildren(document.getElementById(id));
     copySelectionToClipboard();
   }
   function getClipboardData(mime) {
     var transferable = SpecialPowers.Cc['@mozilla.org/widget/transferable;1']
                                     .createInstance(SpecialPowers.Ci.nsITransferable);
     transferable.init(getLoadContext());
     transferable.addDataFlavor(mime);
@@ -100,16 +103,22 @@ function testCopyPaste (isXHTML) {
     return data.value;
   }
   function testPasteText(expected) {
     textarea.value="";
     textarea.focus();
     textarea.editor.paste(1);
     is(textarea.value, expected, "value of the textarea after the paste");
   }
+  function testPasteHTML(id, expected) {
+    var contentEditable = $(id);
+    contentEditable.focus();
+    synthesizeKey("v", {accelKey: 1});
+    is(contentEditable.innerHTML, expected, id+".innerHtml after the paste");
+  }
   function testSelectionToString(expected) {
     is(window.getSelection().toString().replace(/\r\n/g,"\n"), expected, "Selection.toString");
   }
   function testInnerHTML(id, expected) {
     var value = document.getElementById(id).innerHTML;
     is(value, expected, id + ".innerHTML");
   }
   function testEmptyChildren(id) {
@@ -216,16 +225,105 @@ if (false) {
   testSelectionToString("");
 
   copyRangeToClipboard($("div10").childNodes[0],0, $("div10").childNodes[0],1,suppressUnicodeCheckIfHidden);
   testSelectionToString("");
 
   copyRangeToClipboard($("div10").childNodes[1],0, $("div10").childNodes[1],1,suppressUnicodeCheckIfHidden);
   testSelectionToString("");
 
+  if (!isXHTML) {
+    // ============ copy/paste multi-range selection (bug 1123505)
+    // with text start node
+    var sel = window.getSelection();
+    sel.removeAllRanges();
+    var r = document.createRange();
+    var ul = $('ul1');
+    var parent = ul.parentNode;
+    r.setStart(parent, 0);
+    r.setEnd(parent.firstChild, 15);  // the end of "Copy..."
+    sel.addRange(r);
+
+    r = document.createRange();
+    r.setStart(ul, 1);  // before the space inside the UL
+    r.setEnd(parent, 2);  // after the UL
+    sel.addRange(r);
+    copySelectionToClipboard(true);
+    testPasteHTML('contentEditable1', 'Copy1then Paste');
+
+    // with text end node
+    var sel = window.getSelection();
+    sel.removeAllRanges();
+    var r = document.createRange();
+    var ul = $('ul2');
+    var parent = ul.parentNode;
+    r.setStart(parent, 0);
+    r.setEnd(ul, 1);  // after the space
+    sel.addRange(r);
+
+    r = document.createRange();
+    r.setStart(parent.childNodes[1], 0);  // the start of "Copy..."
+    r.setEnd(parent, 2);
+    sel.addRange(r);
+    copySelectionToClipboard(true);
+    testPasteHTML('contentEditable2', 'Copy2then Paste');
+
+    // with text end node and non-empty start
+    var sel = window.getSelection();
+    sel.removeAllRanges();
+    var r = document.createRange();
+    var ul = $('ul3');
+    var parent = ul.parentNode;
+    r.setStart(parent, 0);
+    r.setEnd(ul, 1);  // after the space
+    sel.addRange(r);
+
+    r = document.createRange();
+    r.setStart(parent.childNodes[1], 0);  // the start of "Copy..."
+    r.setEnd(parent, 2);
+    sel.addRange(r);
+    copySelectionToClipboard(true);
+    testPasteHTML('contentEditable3', '<ul id="ul3"><li>\n<br></li></ul>Copy3then Paste');
+
+    // with elements of different depth
+    var sel = window.getSelection();
+    sel.removeAllRanges();
+    var r = document.createRange();
+    var div1 = $('div1s');
+    var parent = div1.parentNode;
+    r.setStart(parent, 0);
+    r.setEnd(document.getElementById('div1se1'), 1);  // after the "inner" DIV
+    sel.addRange(r);
+
+    r = document.createRange();
+    r.setStart(div1.childNodes[1], 0);  // the start of "after"
+    r.setEnd(parent, 1);
+    sel.addRange(r);
+    copySelectionToClipboard(true);
+    testPasteHTML('contentEditable4', '<div id="div1s"><div id="div1se1">before</div></div><div id="div1s">after</div>');
+
+    // with elements of different depth, and a text node at the end
+    var sel = window.getSelection();
+    sel.removeAllRanges();
+    var r = document.createRange();
+    var div1 = $('div2s');
+    var parent = div1.parentNode;
+    r.setStart(parent, 0);
+    r.setEnd(document.getElementById('div2se1'), 1);  // after the "inner" DIV
+    sel.addRange(r);
+
+    r = document.createRange();
+    r.setStart(div1.childNodes[1], 0);  // the start of "after"
+    r.setEnd(parent, 1);
+    sel.addRange(r);
+    copySelectionToClipboard(true);
+    testPasteHTML('contentEditable5', '<div id="div2s"><div id="div2se1">before</div></div><div id="div2s">after</div>');
+
+  }
+
   // ============ copy/paste test from/to a textarea
 
   var val = "1\n 2\n  3";
   textarea.value=val;
   textarea.select();
   textarea.editor.copy();
   
   textarea.value="";
@@ -241,16 +339,31 @@ if (false) {
   testClipboardValue("text/html", "<div id=\"div13\">__</div>");
   testPasteText("__");
 
   // ============ converting cell boundaries to tabs in tables
 
   copyToClipboard($("tr1"));
   testClipboardValue("text/unicode", "foo\tbar");
 
+  // ============ spanning multiple rows
+
+  copyRangeToClipboard($("tr2"),0,$("tr3"),0);
+  testClipboardValue("text/unicode", "1\t2\n3\t4\n");
+  testClipboardValue("text/html", '<table><tbody><tr id="tr2"><tr id="tr2"><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr><tr id="tr3"></tr></tr></tbody></table>');
+
+  // ============ spanning multiple rows in multi-range selection
+
+  clear();
+  addRange($("tr2"),0,$("tr2"),2);
+  addRange($("tr3"),0,$("tr3"),2);
+  copySelectionToClipboard();
+  testClipboardValue("text/unicode", "1\t2\n5\t6");
+  testClipboardValue("text/html", '<table><tbody><tr id="tr2"><td>1</td><td>2</td></tr><tr id="tr3"><td>5</td><td>6</td></tr></tbody></table>');
+
   // ============ manipulating Selection in oncopy
 
   copyRangeToClipboard($("div11").childNodes[0],0, $("div11").childNodes[1],2);
   testClipboardValue("text/unicode", "Xdiv11");
   testClipboardValue("text/html", "<div><p>X<span>div</span>11</p></div>");
   setTimeout(function(){testSelectionToString("div11")},0);
 
   setTimeout(function(){
--- a/dom/base/test/test_copypaste.html
+++ b/dom/base/test/test_copypaste.html
@@ -1,15 +1,16 @@
 <!DOCTYPE HTML>
 <html>
 <!--
 -->
 <head>
   <title>Test for copy/paste</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <script type="text/javascript" src="copypaste.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=524975">Mozilla Bug </a>
 <p id="display"></p>
 <div id="content" style="display: none">
 </div>
@@ -58,16 +59,35 @@ addLoadEvent(function () testCopyPaste(f
 <div id="div4">
   T<textarea>t t t</textarea>
 </div>
 
 <div id="div5">
   T<textarea>     </textarea>
 </div>
 
+<div>Copy1then Paste<ul id="ul1"><li>LI</li>
+</ul></div>
+
+<div><ul id="ul2">
+<li>LI</li></ul>Copy2then Paste</div>
+
+<div><ul id="ul3"><li>
+<li>LI</li></ul>Copy3then Paste</div>
+
+<div><div id="div1s"><div id="div1se1">before<div>inner</div></div>after</div></div>
+<div><div id="div2s"><div id="div2se1">before<div>inner</div></div>after</div>
+</div>
+
+<div id="contentEditable1" contenteditable spellcheck="false"></div>
+<div id="contentEditable2" contenteditable spellcheck="false"></div>
+<div id="contentEditable3" contenteditable spellcheck="false"></div>
+<div id="contentEditable4" contenteditable spellcheck="false"></div>
+<div id="contentEditable5" contenteditable spellcheck="false"></div>
+
 <div id="div6" style="display:none"></div>
 <script>
 var x = $("div6")
 x.appendChild(document.createTextNode('di'))
 x.appendChild(document.createTextNode('v6'))
 </script>
 
 <div id="div7" style="display:none">div7</div>
@@ -81,12 +101,13 @@ x.appendChild(document.createTextNode('1
 </script>
 
 <div id="div11" oncopy="modifySelection('X')"><span>div</span>11</div>
 <div id="div12" oncopy="modifySelection('X<b style=\'display:none\'>Y</b>')"><span>div</span>12</div>
 
 <div id="div13">_<noscript>FAIL</noscript>_</div>
 
 <table><tr id=tr1><td>foo</td><td>bar</td></tr></table>
+<table><tr id=tr2><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr><tr id=tr3><td>5</td><td>6</td></tr></table>
 
 </div>
 </body>
 </html>