// 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);
const modifier = (navigator.platform.includes("Mac")) ?
Ci.nsIDOMWindowUtils.MODIFIER_META :
Ci.nsIDOMWindowUtils.MODIFIER_CONTROL;
function sendKey(message) {
BrowserTestUtils.synthesizeKey(message.data.key,
{code: message.data.code, accelKey: true},
browser);
}
browser.messageManager.addMessageListener("Test:SendKey", sendKey);
// 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 ContentTask.spawn(browser, { modifier, htmlPrefix, htmlPostfix }, async function(arg) {
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");
await new Promise((resolve, reject) => {
addEventListener("copy", function copyEvent(event) {
removeEventListener("copy", copyEvent, true);
// The data is empty as the selection is copied during the event default phase.
Assert.equal(event.clipboardData.mozItemCount, 0, "Zero items on clipboard");
resolve();
}, true);
sendAsyncMessage("Test:SendKey", {key: "c"});
});
selection.modify("move", "right", "line");
await new Promise((resolve, reject) => {
addEventListener("paste", function copyEvent(event) {
removeEventListener("paste", copyEvent, true);
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"), arg.htmlPrefix +
"t Bold" + arg.htmlPostfix, "text/html value");
Assert.equal(clipboardData.getData("text/plain"), "t Bold", "text/plain value");
resolve();
}, true);
sendAsyncMessage("Test:SendKey", {key: "v"});
});
Assert.equal(main.innerHTML, "Test Bold After Textt Bold", "Copy and paste html");
selection.modify("extend", "left", "word");
selection.modify("extend", "left", "word");
selection.modify("extend", "left", "character");
await new Promise((resolve, reject) => {
addEventListener("cut", function copyEvent(event) {
removeEventListener("cut", copyEvent, true);
event.clipboardData.setData("text/plain", "Some text");
event.clipboardData.setData("text/html", "Italic ");
selection.deleteFromDocument();
event.preventDefault();
resolve();
}, true);
sendAsyncMessage("Test:SendKey", {key: "x"});
});
selection.modify("move", "left", "line");
await new Promise((resolve, reject) => {
addEventListener("paste", function copyEvent(event) {
removeEventListener("paste", copyEvent, true);
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"), arg.htmlPrefix +
"Italic " + arg.htmlPostfix, "text/html value 2");
Assert.equal(clipboardData.getData("text/plain"), "Some text", "text/plain value 2");
resolve();
}, true);
sendAsyncMessage("Test:SendKey", {key: "v"});
});
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);
await ContentTask.spawn(browser, { modifier, htmlPrefix, htmlPostfix }, async function(arg) {
var doc = content.document;
var main = doc.getElementById("main");
main.focus();
await new Promise((resolve, reject) => {
addEventListener("paste", function copyEvent(event) {
removeEventListener("paste", copyEvent, true);
let clipboardData = event.clipboardData;
// DataTransfer doesn't support the image types yet, so only text/html
// will be present.
if (clipboardData.getData("text/html") !== arg.htmlPrefix +
'
' +
arg.htmlPostfix) {
reject("Clipboard Data did not contain an image, was " + clipboardData.getData("text/html"));
}
resolve();
}, true);
sendAsyncMessage("Test:SendKey", {key: "v"});
});
// The new content should now include an image.
Assert.equal(main.innerHTML, 'Italic
' +
"Test Bold After", "Paste after copy image");
});
browser.messageManager.removeMessageListener("Test:SendKey", sendKey);
gBrowser.removeCurrentTab();
});