// This test is used to check copy and paste in editable areas to ensure that non-text // types (html and images) are copied to and pasted from the clipboard properly. var testPage = "" + " " + "
Test Bold After Text
" + ""; add_task(async function () { let tab = BrowserTestUtils.addTab(gBrowser); let browser = gBrowser.getBrowserForTab(tab); gBrowser.selectedTab = tab; await promiseTabLoadEvent(tab, "data:text/html," + escape(testPage)); await SimpleTest.promiseFocus(browser); function sendKey(key, code) { return BrowserTestUtils.synthesizeKey( key, { code, accelKey: true }, browser ); } // On windows, HTML clipboard includes extra data. // The values are from widget/windows/nsDataObj.cpp. const htmlPrefix = navigator.platform.includes("Win") ? "\n" : ""; const htmlPostfix = navigator.platform.includes("Win") ? "\n\n" : ""; await SpecialPowers.spawn(browser, [], () => { var doc = content.document; var main = doc.getElementById("main"); main.focus(); // Select an area of the text. let selection = doc.getSelection(); selection.modify("move", "left", "line"); selection.modify("move", "right", "character"); selection.modify("move", "right", "character"); selection.modify("move", "right", "character"); selection.modify("extend", "right", "word"); selection.modify("extend", "right", "word"); }); // The data is empty as the selection was copied during the event default phase. let copyEventPromise = BrowserTestUtils.waitForContentEvent( browser, "copy", false, event => { return event.clipboardData.mozItemCount == 0; } ); await SpecialPowers.spawn(browser, [], () => {}); await sendKey("c"); await copyEventPromise; let pastePromise = SpecialPowers.spawn( browser, [htmlPrefix, htmlPostfix], (htmlPrefixChild, htmlPostfixChild) => { let selection = content.document.getSelection(); selection.modify("move", "right", "line"); return new Promise((resolve, reject) => { content.addEventListener( "paste", event => { let clipboardData = event.clipboardData; Assert.equal( clipboardData.mozItemCount, 1, "One item on clipboard" ); Assert.equal( clipboardData.types.length, 2, "Two types on clipboard" ); Assert.equal( clipboardData.types[0], "text/html", "text/html on clipboard" ); Assert.equal( clipboardData.types[1], "text/plain", "text/plain on clipboard" ); Assert.equal( clipboardData.getData("text/html"), htmlPrefixChild + "t Bold" + htmlPostfixChild, "text/html value" ); Assert.equal( clipboardData.getData("text/plain"), "t Bold", "text/plain value" ); resolve(); }, { capture: true, once: true } ); }); } ); await SpecialPowers.spawn(browser, [], () => {}); await sendKey("v"); await pastePromise; let copyPromise = SpecialPowers.spawn(browser, [], () => { var main = content.document.getElementById("main"); Assert.equal( main.innerHTML, "Test Bold After Textt Bold", "Copy and paste html" ); let selection = content.document.getSelection(); selection.modify("extend", "left", "word"); selection.modify("extend", "left", "word"); selection.modify("extend", "left", "character"); return new Promise((resolve, reject) => { content.addEventListener( "cut", event => { event.clipboardData.setData("text/plain", "Some text"); event.clipboardData.setData("text/html", "Italic "); selection.deleteFromDocument(); event.preventDefault(); resolve(); }, { capture: true, once: true } ); }); }); await SpecialPowers.spawn(browser, [], () => {}); await sendKey("x"); await copyPromise; pastePromise = SpecialPowers.spawn( browser, [htmlPrefix, htmlPostfix], (htmlPrefixChild, htmlPostfixChild) => { let selection = content.document.getSelection(); selection.modify("move", "left", "line"); return new Promise((resolve, reject) => { content.addEventListener( "paste", event => { let clipboardData = event.clipboardData; Assert.equal( clipboardData.mozItemCount, 1, "One item on clipboard 2" ); Assert.equal( clipboardData.types.length, 2, "Two types on clipboard 2" ); Assert.equal( clipboardData.types[0], "text/html", "text/html on clipboard 2" ); Assert.equal( clipboardData.types[1], "text/plain", "text/plain on clipboard 2" ); Assert.equal( clipboardData.getData("text/html"), htmlPrefixChild + "Italic " + htmlPostfixChild, "text/html value 2" ); Assert.equal( clipboardData.getData("text/plain"), "Some text", "text/plain value 2" ); resolve(); }, { capture: true, once: true } ); }); } ); await SpecialPowers.spawn(browser, [], () => {}); await sendKey("v"); await pastePromise; await SpecialPowers.spawn(browser, [], () => { var main = content.document.getElementById("main"); Assert.equal( main.innerHTML, "Italic Test Bold After", "Copy and paste html 2" ); }); // Next, check that the Copy Image command works. // The context menu needs to be opened to properly initialize for the copy // image command to run. let contextMenu = document.getElementById("contentAreaContextMenu"); let contextMenuShown = promisePopupShown(contextMenu); BrowserTestUtils.synthesizeMouseAtCenter( "#img", { type: "contextmenu", button: 2 }, gBrowser.selectedBrowser ); await contextMenuShown; document.getElementById("context-copyimage-contents").doCommand(); contextMenu.hidePopup(); await promisePopupHidden(contextMenu); // Focus the content again await SimpleTest.promiseFocus(browser); pastePromise = SpecialPowers.spawn( browser, [htmlPrefix, htmlPostfix], (htmlPrefixChild, htmlPostfixChild) => { var doc = content.document; var main = doc.getElementById("main"); main.focus(); return new Promise((resolve, reject) => { content.addEventListener( "paste", event => { let clipboardData = event.clipboardData; // DataTransfer doesn't support the image types yet, so only text/html // will be present. if ( clipboardData.getData("text/html") !== htmlPrefixChild + '' + htmlPostfixChild ) { reject( "Clipboard Data did not contain an image, was " + clipboardData.getData("text/html") ); } resolve(); }, { capture: true, once: true } ); }); } ); await SpecialPowers.spawn(browser, [], () => {}); await sendKey("v"); await pastePromise; // The new content should now include an image. await SpecialPowers.spawn(browser, [], () => { var main = content.document.getElementById("main"); Assert.equal( main.innerHTML, 'Italic ' + "Test Bold After", "Paste after copy image" ); }); gBrowser.removeCurrentTab(); });