<!DOCTYPE HTML> <html><head> <title>Test for bug 525389</title> <style src="/tests/SimpleTest/test.css" type="text/css"></style> <script src="/tests/SimpleTest/SimpleTest.js"></script> <script src="/tests/SimpleTest/EventUtils.js"></script> <script class="testbody" type="application/javascript"> var utils = SpecialPowers.getDOMWindowUtils(window); var Cc = SpecialPowers.Cc; var Ci = SpecialPowers.Ci; function getLoadContext() { return SpecialPowers.wrap(window).docShell.QueryInterface(Ci.nsILoadContext); } async function runTest() { var pasteCount = 0; var pasteFunc = function(event) { pasteCount++; }; function verifyContent(s) { var e = document.getElementById("i1"); var doc = e.contentDocument; if (navigator.platform.includes("Win")) { // On Windows ignore \n which got left over from the removal of the fragment tags // <html><body>\n<!--StartFragment--> and <!--EndFragment-->\n</body>\n</html>. is(doc.body.innerHTML.replace(/\n/g, ""), s, ""); } else { is(doc.body.innerHTML, s, ""); } } function pasteInto(trans, html, target_id) { var e = document.getElementById("i1"); var doc = e.contentDocument; doc.designMode = "on"; doc.body.innerHTML = html; doc.defaultView.focus(); if (target_id) e = doc.getElementById(target_id); else e = doc.body; var selection = doc.defaultView.getSelection(); selection.removeAllRanges(); selection.selectAllChildren(e); selection.collapseToEnd(); pasteCount = 0; e.addEventListener("paste", pasteFunc); utils.sendContentCommandEvent("pasteTransferable", trans); e.removeEventListener("paste", pasteFunc); return e; } function getTransferableFromClipboard(asHTML) { var trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable); trans.init(getLoadContext()); if (asHTML) { trans.addDataFlavor("text/html"); } else { trans.addDataFlavor("text/plain"); } var clip = SpecialPowers.Services.clipboard; clip.getData(trans, Ci.nsIClipboard.kGlobalClipboard); return trans; } // Commented out as the test for it below is also commented out. // function makeTransferable(s, asHTML, target_id) { // var e = document.getElementById("i2"); // var doc = e.contentDocument; // if (asHTML) { // doc.body.innerHTML = s; // } else { // var text = doc.createTextNode(s); // doc.body.appendChild(text); // } // doc.designMode = "on"; // doc.defaultView.focus(); // var selection = doc.defaultView.getSelection(); // selection.removeAllRanges(); // if (!target_id) { // selection.selectAllChildren(doc.body); // } else { // var range = document.createRange(); // range.selectNode(doc.getElementById(target_id)); // selection.addRange(range); // } // // // We cannot use plain strings, we have to use nsSupportsString. // var supportsStringClass = SpecialPowers.Components.classes["@mozilla.org/supports-string;1"]; // var ssData = supportsStringClass.createInstance(Ci.nsISupportsString); // // // Create the transferable. // var trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable); // trans.init(getLoadContext()); // // // Add the data to the transferable. // if (asHTML) { // trans.addDataFlavor("text/html"); // ssData.data = doc.body.innerHTML; // trans.setTransferData("text/html", ssData); // } else { // trans.addDataFlavor("text/plain"); // ssData.data = doc.body.innerHTML; // trans.setTransferData("text/plain", ssData); // } // // return trans; // } async function copyToClipBoard(s, asHTML, target_id) { var e = document.getElementById("i2"); var doc = e.contentDocument; if (asHTML) { doc.body.innerHTML = s; } else { var text = doc.createTextNode(s); doc.body.appendChild(text); } doc.designMode = "on"; doc.defaultView.focus(); var selection = doc.defaultView.getSelection(); selection.removeAllRanges(); if (!target_id) { selection.selectAllChildren(doc.body); } else { var range = document.createRange(); range.selectNode(doc.getElementById(target_id)); selection.addRange(range); } await SimpleTest.promiseClipboardChange(() => true, () => { SpecialPowers.wrap(doc).execCommand("copy", false, null); }); return e; } await copyToClipBoard("<span>Hello</span><span>Kitty</span>", true); var trans = getTransferableFromClipboard(true); pasteInto(trans, ""); verifyContent("<span>Hello</span><span>Kitty</span>"); is(pasteCount, 1, "paste event was not triggered"); // this test is not working out exactly like the clipboard test // has to do with generating the nsITransferable above // trans = makeTransferable('<span>Hello</span><span>Kitty</span>', true); // pasteInto(trans, ''); // verifyContent('<span>Hello</span><span>Kitty</span>'); await copyToClipBoard("<dl><dd>Hello Kitty</dd></dl><span>Hello</span><span>Kitty</span>", true); trans = getTransferableFromClipboard(true); pasteInto(trans, '<ol><li id="paste_here">X</li></ol>', "paste_here"); verifyContent('<ol><li id="paste_here">X<dl><dd>Hello Kitty</dd></dl><span>Hello</span><span>Kitty</span></li></ol>'); is(pasteCount, 1, "paste event was not triggered"); // The following test doesn't do what I expected, because the special handling // of IsList nodes in nsHTMLEditor::InsertHTMLWithContext simply removes // non-list/item children. See bug 481177. // await copyToClipBoard("<ol><li>Hello Kitty</li><span>Hello</span></ol>", true); // pasteInto('<ol><li id="paste_here">X</li></ol>',"paste_here"); // verifyContent('<ol><li id="paste_here">X</li><li>Hello Kitty</li><span>Hello</span></ol>'); await copyToClipBoard("<pre>Kitty</pre><span>Hello</span>", true); trans = getTransferableFromClipboard(true); pasteInto(trans, '<pre id="paste_here">Hello </pre>', "paste_here"); verifyContent('<pre id="paste_here">Hello Kitty<span>Hello</span></pre>'); is(pasteCount, 1, "paste event was not triggered"); await copyToClipBoard('1<span style="display: contents">2</span>3', true); trans = getTransferableFromClipboard(true); pasteInto(trans, '<div id="paste_here"></div>', "paste_here"); verifyContent('<div id="paste_here">1<span style="display: contents">2</span>3</div>'); is(pasteCount, 1, "paste event was not triggered"); // test that we can preventDefault pastes pasteFunc = function(event) { event.preventDefault(); return false; }; await copyToClipBoard("<pre>Kitty</pre><span>Hello</span>", true); trans = getTransferableFromClipboard(true); pasteInto(trans, '<pre id="paste_here">Hello </pre>', "paste_here"); verifyContent('<pre id="paste_here">Hello </pre>'); is(pasteCount, 0, "paste event was triggered"); } SimpleTest.waitForExplicitFinish(); addLoadEvent(() => { add_task(async function test_copy() { await runTest(); }); }); </script> </head> <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=525389">Mozilla Bug 525389</a> <p id="display"></p> <pre id="test"> </pre> <iframe id="i1" width="200" height="100" src="about:blank"></iframe><br> <iframe id="i2" width="200" height="100" src="about:blank"></iframe><br> </body> </html>