test_paste_image.html (7121B)
1 <html><head> 2 <title>Test for bug 891247</title> 3 <link rel="stylesheet" href="/tests/SimpleTest/test.css"> 4 <script src="/tests/SimpleTest/SimpleTest.js"></script> 5 <script src="/tests/SimpleTest/EventUtils.js"></script> 6 7 <script class="testbody" type="application/javascript"> 8 function ImageTester() { 9 var counter = 0; 10 var images = []; 11 var that = this; 12 13 this.add = function(aFile) { 14 images.push(aFile); 15 }; 16 17 this.test = async function() { 18 for (var i = 0; i < images.length; i++) { 19 await testImageSize(images[i]); 20 } 21 }; 22 23 this.returned = function() { 24 counter++; 25 info("returned=" + counter + " images.length=" + images.length); 26 if (counter == images.length) { 27 info("test finish"); 28 } 29 }; 30 31 async function testImageSize(aFile) { 32 var source = window.URL.createObjectURL(aFile); 33 var image = new Image(); 34 image.src = source; 35 var imageTester = that; 36 let promise = new Promise(resolve => { 37 image.addEventListener("load", function(e) { 38 is(this.width, 62, "Check generated image width"); 39 is(this.height, 71, "Check generated image height"); 40 41 // This fails on OSX only. 42 if (!navigator.platform.includes("Mac")) { 43 testImageCanvas(image); 44 } 45 46 imageTester.returned(); 47 resolve(); 48 }, { once: true }); 49 }); 50 51 document.body.appendChild(image); 52 await promise; 53 }; 54 55 function testImageCanvas(aImage) { 56 var canvas = drawToCanvas(aImage); 57 58 var refImage = document.getElementById('image'); 59 var refCanvas = drawToCanvas(refImage); 60 61 is(canvas.toDataURL(), refCanvas.toDataURL(), "Image should map pixel-by-pixel"); 62 } 63 64 function drawToCanvas(aImage) { 65 var canvas = document.createElement("CANVAS"); 66 document.body.appendChild(canvas); 67 canvas.width = aImage.width; 68 canvas.height = aImage.height; 69 canvas.getContext('2d').drawImage(aImage, 0, 0); 70 return canvas; 71 } 72 } 73 74 function copyImage(aImageId) { 75 // selection of the node 76 var node = document.getElementById(aImageId); 77 var docShell = SpecialPowers.wrap(window).docShell; 78 79 // let's copy the node 80 var documentViewer = docShell.docViewer 81 .QueryInterface(SpecialPowers.Ci.nsIDocumentViewerEdit); 82 documentViewer.setCommandNode(node); 83 documentViewer.copyImage(documentViewer.COPY_IMAGE_ALL); 84 } 85 86 async function doTest(imageAsFileEnabled) { 87 await SpecialPowers.pushPrefEnv({ 88 set: [["clipboard.imageAsFile.enabled", imageAsFileEnabled]], 89 }); 90 91 copyImage('image'); 92 93 //--------- now check the content of the clipboard 94 var clipboard = SpecialPowers.Cc["@mozilla.org/widget/clipboard;1"] 95 .getService(SpecialPowers.Ci.nsIClipboard); 96 // does the clipboard contain text/plain data ? 97 ok(clipboard.hasDataMatchingFlavors(["text/plain"], clipboard.kGlobalClipboard), 98 "clipboard contains unicode text"); 99 // does the clipboard contain text/html data ? 100 ok(clipboard.hasDataMatchingFlavors(["text/html"], clipboard.kGlobalClipboard), 101 "clipboard contains html text"); 102 // does the clipboard contain image data ? 103 ok(clipboard.hasDataMatchingFlavors(["image/png"], clipboard.kGlobalClipboard), 104 "clipboard contains image"); 105 106 let promise = new Promise(resolve => { 107 window.addEventListener("paste", async (e) => { 108 isDeeply(e.clipboardData.types, 109 (navigator.platform.includes("Win") && imageAsFileEnabled) ? 110 ["application/x-moz-file", "Files"] : ["text/html", "text/plain", "Files"]); 111 await onPaste(e, imageAsFileEnabled); 112 resolve(); 113 }, { once: true }); 114 }); 115 116 var textarea = SpecialPowers.wrap(document.getElementById('textarea')); 117 textarea.focus(); 118 textarea.editor.paste(clipboard.kGlobalClipboard); 119 120 await promise; 121 122 clipboard.emptyClipboard(clipboard.kGlobalClipboard); 123 } 124 125 async function onPaste(e, imageAsFileEnabled) { 126 var imageTester = new ImageTester; 127 testFiles(e, imageTester, imageAsFileEnabled); 128 testItems(e, imageTester); 129 await imageTester.test(); 130 } 131 132 function testItems(e, imageTester) { 133 var items = e.clipboardData.items; 134 is(items, e.clipboardData.items, 135 "Getting @items twice should return the same object"); 136 var haveFiles = false; 137 ok(items instanceof DataTransferItemList, "@items implements DataTransferItemList"); 138 ok(items.length, "@items is not empty"); 139 for (var i = 0; i < items.length; i++) { 140 var item = items[i]; 141 ok(item instanceof DataTransferItem, "each element of @items must implement DataTransferItem"); 142 if (item.kind == "file") { 143 var file = item.getAsFile(); 144 ok(file instanceof File, ".getAsFile() returns a File object"); 145 ok(file.size > 0, "Files shouldn't have size 0"); 146 imageTester.add(file); 147 } 148 } 149 } 150 151 function testFiles(e, imageTester, imageAsFileEnabled) { 152 var files = e.clipboardData.files; 153 154 is(files, e.clipboardData.files, 155 "Getting the files array twice should return the same array"); 156 is(files.length, 1, "There should be one file in the clipboard"); 157 for (var i = 0; i < files.length; i++) { 158 var file = files[i]; 159 ok(file instanceof File, ".files should contain only File objects"); 160 ok(file.size > 0, "This file shouldn't have size 0"); 161 if (navigator.platform.includes("Win") && imageAsFileEnabled) { 162 ok(file.name.startsWith("Untitled") && file.name.endsWith(".png"), 163 `Check filename, got "${file.name}"`); 164 } else { 165 is(file.name, "image.png", "Check filename"); 166 } 167 168 testSlice(file); 169 imageTester.add(file); 170 // Adding the same image again so we can test concurrency 171 imageTester.add(file); 172 } 173 } 174 175 function testSlice(aFile) { 176 var blob = aFile.slice(); 177 ok(blob instanceof Blob, ".slice returns a blob"); 178 is(blob.size, aFile.size, "the blob has the same size"); 179 180 blob = aFile.slice(123123); 181 is(blob.size, 0, ".slice overflow check"); 182 183 blob = aFile.slice(123, 123141); 184 is(blob.size, aFile.size - 123, ".slice @size check"); 185 186 blob = aFile.slice(123, 12); 187 is(blob.size, 0, ".slice @size check 2"); 188 189 blob = aFile.slice(124, 134, "image/png"); 190 is(blob.size, 10, ".slice @size check 3"); 191 is(blob.type, "image/png", ".slice @type check"); 192 } 193 194 add_task(async function test_imageAsFile_enabled() { 195 await doTest(true); 196 }); 197 198 add_task(async function test_imageAsFile_disabled() { 199 await doTest(false); 200 }); 201 202 </script> 203 <body> 204 <img id="image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABHCA 205 IAAADQjmMaAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3goUAwAgSAORBwAAABl0RVh0Q29 206 tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAABPSURBVGje7c4BDQAACAOga//OmuMbJGAurTbq 207 6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6s31B0IqAY2/t 208 QVCAAAAAElFTkSuQmCC" /> 209 <form> 210 <textarea id="textarea"></textarea> 211 </form> 212 </body> 213 </html>