diff options
Diffstat (limited to 'dom/base/test/copypaste.js')
-rw-r--r-- | dom/base/test/copypaste.js | 412 |
1 files changed, 412 insertions, 0 deletions
diff --git a/dom/base/test/copypaste.js b/dom/base/test/copypaste.js new file mode 100644 index 000000000..6fa3cb909 --- /dev/null +++ b/dom/base/test/copypaste.js @@ -0,0 +1,412 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function modifySelection(s) { + var g = window.getSelection(); + var l = g.getRangeAt(0); + var d = document.createElement("p"); + d.innerHTML = s; + d.appendChild(l.cloneContents()); + + var e = document.createElement("div"); + document.body.appendChild(e); + e.appendChild(d); + var a = document.createRange(); + a.selectNode(d); + g.removeAllRanges(); + g.addRange(a); + window.setTimeout(function () { + e.parentNode.removeChild(e); + g.removeAllRanges(); + g.addRange(l); + }, 0) +} + +function getLoadContext() { + var Ci = SpecialPowers.Ci; + return SpecialPowers.wrap(window).QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsILoadContext); +} + +function testCopyPaste (isXHTML) { + var suppressUnicodeCheckIfHidden = !!isXHTML; + var suppressHTMLCheck = !!isXHTML; + + var webnav = SpecialPowers.wrap(window).QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) + .getInterface(SpecialPowers.Ci.nsIWebNavigation) + + var docShell = webnav.QueryInterface(SpecialPowers.Ci.nsIDocShell); + + var documentViewer = docShell.contentViewer + .QueryInterface(SpecialPowers.Ci.nsIContentViewerEdit); + + var clipboard = SpecialPowers.Services.clipboard; + + var textarea = SpecialPowers.wrap(document.getElementById('input')); + + 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 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 addRange(startNode,startIndex,endNode,endIndex) { + var sel = window.getSelection(); + var r = document.createRange(); + r.setStart(startNode,startIndex) + r.setEnd(endNode,endIndex) + sel.addRange(r); + } + function copyRangeToClipboard(startNode,startIndex,endNode,endIndex,suppressUnicodeCheck) { + clear(); + addRange(startNode,startIndex,endNode,endIndex); + copySelectionToClipboard(suppressUnicodeCheck); + } + function copyChildrenToClipboard(id) { + 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); + clipboard.getData(transferable, 1); + var data = SpecialPowers.createBlankObject(); + transferable.getTransferData(mime, data, {}) ; + return data; + } + function testHtmlClipboardValue(mime, expected) { + // For Windows, navigator.platform returns "Win32". + var expectedValue = expected; + if (navigator.platform.indexOf("Win") >= 0) { + // Windows has extra content. + var expectedValue = "<html><body>\n<!--StartFragment-->" + + expected.replace(/\n/g, '\n') + + "<!--EndFragment-->\n</body>\n</html>"; + } + testClipboardValue(mime, expectedValue); + } + function testClipboardValue(mime, expected) { + if (suppressHTMLCheck && mime == "text/html") + return null; + var data = SpecialPowers.wrap(getClipboardData(mime)); + is (data.value == null ? data.value : + data.value.QueryInterface(SpecialPowers.Ci.nsISupportsString).data, + expected, + mime + " value in the clipboard"); + 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: true}); + 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) { + copyChildrenToClipboard(id); + testSelectionToString(""); + testClipboardValue("text/unicode", null); + testClipboardValue("text/html", null); + testPasteText(""); + } + + copyChildrenToClipboard("draggable"); + testSelectionToString("This is a draggable bit of text."); + testClipboardValue("text/unicode", + "This is a draggable bit of text."); + testHtmlClipboardValue("text/html", + "<div id=\"draggable\" title=\"title to have a long HTML line\">This is a <em>draggable</em> bit of text.</div>"); + testPasteText("This is a draggable bit of text."); + + copyChildrenToClipboard("alist"); + testSelectionToString(" bla\n\n foo\n bar\n\n"); + testClipboardValue("text/unicode", " bla\n\n foo\n bar\n\n"); + testHtmlClipboardValue("text/html", "<div id=\"alist\">\n bla\n <ul>\n <li>foo</li>\n \n <li>bar</li>\n </ul>\n </div>"); + testPasteText(" bla\n\n foo\n bar\n\n"); + + copyChildrenToClipboard("blist"); + testSelectionToString(" mozilla\n\n foo\n bar\n\n"); + testClipboardValue("text/unicode", " mozilla\n\n foo\n bar\n\n"); + testHtmlClipboardValue("text/html", "<div id=\"blist\">\n mozilla\n <ol>\n <li>foo</li>\n \n <li>bar</li>\n </ol>\n </div>"); + testPasteText(" mozilla\n\n foo\n bar\n\n"); + + copyChildrenToClipboard("clist"); + testSelectionToString(" mzla\n\n foo\n bazzinga!\n bar\n\n"); + testClipboardValue("text/unicode", " mzla\n\n foo\n bazzinga!\n bar\n\n"); + testHtmlClipboardValue("text/html", "<div id=\"clist\">\n mzla\n <ul>\n <li>foo<ul>\n <li>bazzinga!</li>\n </ul></li>\n \n <li>bar</li>\n </ul>\n </div>"); + testPasteText(" mzla\n\n foo\n bazzinga!\n bar\n\n"); + + copyChildrenToClipboard("div4"); + testSelectionToString(" Tt t t "); + testClipboardValue("text/unicode", " Tt t t "); + if (isXHTML) { + testHtmlClipboardValue("text/html", "<div id=\"div4\">\n T<textarea xmlns=\"http://www.w3.org/1999/xhtml\">t t t</textarea>\n</div>"); + testInnerHTML("div4", "\n T<textarea xmlns=\"http://www.w3.org/1999/xhtml\">t t t</textarea>\n"); + } + else { + testHtmlClipboardValue("text/html", "<div id=\"div4\">\n T<textarea>t t t</textarea>\n</div>"); + testInnerHTML("div4", "\n T<textarea>t t t</textarea>\n"); + } + testPasteText(" Tt t t "); + + copyChildrenToClipboard("div5"); + testSelectionToString(" T "); + testClipboardValue("text/unicode", " T "); + if (isXHTML) { + testHtmlClipboardValue("text/html", "<div id=\"div5\">\n T<textarea xmlns=\"http://www.w3.org/1999/xhtml\"> </textarea>\n</div>"); + testInnerHTML("div5", "\n T<textarea xmlns=\"http://www.w3.org/1999/xhtml\"> </textarea>\n"); + } + else { + testHtmlClipboardValue("text/html", "<div id=\"div5\">\n T<textarea> </textarea>\n</div>"); + testInnerHTML("div5", "\n T<textarea> </textarea>\n"); + } + testPasteText(" T "); + + copyRangeToClipboard($("div6").childNodes[0],0, $("div6").childNodes[1],1,suppressUnicodeCheckIfHidden); + testSelectionToString(""); +// START Disabled due to bug 564688 +if (false) { + testClipboardValue("text/unicode", ""); + testClipboardValue("text/html", ""); +} +// END Disabled due to bug 564688 + testInnerHTML("div6", "div6"); + + copyRangeToClipboard($("div7").childNodes[0],0, $("div7").childNodes[0],4,suppressUnicodeCheckIfHidden); + testSelectionToString(""); +// START Disabled due to bug 564688 +if (false) { + testClipboardValue("text/unicode", ""); + testClipboardValue("text/html", ""); +} +// END Disabled due to bug 564688 + testInnerHTML("div7", "div7"); + + copyRangeToClipboard($("div8").childNodes[0],0, $("div8").childNodes[0],4,suppressUnicodeCheckIfHidden); + testSelectionToString(""); +// START Disabled due to bug 564688 +if (false) { + testClipboardValue("text/unicode", ""); + testClipboardValue("text/html", ""); +} +// END Disabled due to bug 564688 + testInnerHTML("div8", "div8"); + + copyRangeToClipboard($("div9").childNodes[0],0, $("div9").childNodes[0],4,suppressUnicodeCheckIfHidden); + testSelectionToString("div9"); + testClipboardValue("text/unicode", "div9"); + testHtmlClipboardValue("text/html", "div9"); + testInnerHTML("div9", "div9"); + + copyToClipboard($("div10"), suppressUnicodeCheckIfHidden); + testSelectionToString(""); + testInnerHTML("div10", "div10"); + + copyToClipboard($("div10").firstChild, suppressUnicodeCheckIfHidden); + 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>'); + + // crash test for bug 1127835 + var e1 = document.getElementById('1127835crash1'); + var e2 = document.getElementById('1127835crash2'); + var e3 = document.getElementById('1127835crash3'); + var t1 = e1.childNodes[0]; + var t3 = e3.childNodes[0]; + + var sel = window.getSelection(); + sel.removeAllRanges(); + + var r = document.createRange(); + r.setStart(t1, 1); + r.setEnd(e2, 0); + sel.addRange(r); + + r = document.createRange(); + r.setStart(e2, 1); + r.setEnd(t3, 0); + sel.addRange(r); + copySelectionToClipboard(true); + testPasteHTML('contentEditable6', '<span id="1127835crash1"></span><div id="1127835crash2"><div>\n</div></div><br>'); + } + + // ============ copy/paste test from/to a textarea + + var val = "1\n 2\n 3"; + textarea.value=val; + textarea.select(); + textarea.editor.copy(); + + textarea.value=""; + textarea.editor.paste(1); + is(textarea.value, val); + textarea.value=""; + + // ============ NOSCRIPT should not be copied + + copyChildrenToClipboard("div13"); + testSelectionToString("__"); + testClipboardValue("text/unicode", "__"); + testHtmlClipboardValue("text/html", "<div id=\"div13\">__</div>"); + testPasteText("__"); + + // ============ converting cell boundaries to tabs in tables + + copyToClipboard($("tr1")); + testClipboardValue("text/unicode", "foo\tbar"); + + if (!isXHTML) { + // ============ spanning multiple rows + + copyRangeToClipboard($("tr2"),0,$("tr3"),0); + testClipboardValue("text/unicode", "1\t2\n3\t4\n"); + testHtmlClipboardValue("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"); + testHtmlClipboardValue("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"); + testHtmlClipboardValue("text/html", "<div><p>X<span>div</span>11</p></div>"); + setTimeout(function(){testSelectionToString("div11")},0); + + setTimeout(function(){ + copyRangeToClipboard($("div12").childNodes[0],0, $("div12").childNodes[1],2); + testClipboardValue("text/unicode", "Xdiv12"); + testHtmlClipboardValue("text/html", "<div><p>X<span>div</span>12</p></div>"); + setTimeout(function(){ + testSelectionToString("div12"); + setTimeout(SimpleTest.finish,0); + },0); + },0); +} |