browser_clipboard_pastefile.js (3951B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 // Test that (real) files can be pasted into chrome/content. 6 // Pasting files should also hide all other data from content. 7 8 function setClipboard(path) { 9 const file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); 10 file.initWithPath(path); 11 12 const trans = Cc["@mozilla.org/widget/transferable;1"].createInstance( 13 Ci.nsITransferable 14 ); 15 trans.init(null); 16 trans.addDataFlavor("application/x-moz-file"); 17 trans.setTransferData("application/x-moz-file", file); 18 19 trans.addDataFlavor("text/plain"); 20 const str = Cc["@mozilla.org/supports-string;1"].createInstance( 21 Ci.nsISupportsString 22 ); 23 str.data = "Alternate"; 24 trans.setTransferData("text/plain", str); 25 26 // Write to clipboard. 27 Services.clipboard.setData(trans, null, Ci.nsIClipboard.kGlobalClipboard); 28 } 29 30 add_task(async function () { 31 await SpecialPowers.pushPrefEnv({ 32 set: [["dom.events.dataTransfer.mozFile.enabled", true]], 33 }); 34 35 // Create a temporary file that will be pasted. 36 const file = await IOUtils.createUniqueFile( 37 PathUtils.tempDir, 38 "test-file.txt", 39 0o600 40 ); 41 await IOUtils.writeUTF8(file, "Hello World!"); 42 43 // Put the data directly onto the native clipboard to make sure 44 // it isn't handled internally in Gecko somehow. 45 setClipboard(file); 46 47 let tab = await BrowserTestUtils.openNewForegroundTab( 48 gBrowser, 49 "https://example.com/browser/browser/base/content/test/general/clipboard_pastefile.html" 50 ); 51 let browser = tab.linkedBrowser; 52 53 let resultPromise = SpecialPowers.spawn(browser, [], function () { 54 return new Promise(resolve => { 55 content.document.addEventListener("testresult", event => { 56 resolve(event.detail.result); 57 }); 58 }); 59 }); 60 61 // Focus <input> in content 62 await SpecialPowers.spawn(browser, [], async function () { 63 content.document.getElementById("input").focus(); 64 }); 65 66 // Paste file into <input> in content 67 await BrowserTestUtils.synthesizeKey("v", { accelKey: true }, browser); 68 69 let result = await resultPromise; 70 is(result, PathUtils.filename(file), "Correctly pasted file in content"); 71 72 var input = document.createElement("input"); 73 document.documentElement.appendChild(input); 74 input.focus(); 75 76 await new Promise(resolve => { 77 input.addEventListener( 78 "paste", 79 function (event) { 80 let dt = event.clipboardData; 81 is(dt.types.length, 3, "number of types"); 82 ok(dt.types.includes("text/plain"), "text/plain exists in types"); 83 ok( 84 dt.types.includes("application/x-moz-file"), 85 "application/x-moz-file exists in types" 86 ); 87 is(dt.types[2], "Files", "Last type should be 'Files'"); 88 ok( 89 dt.mozTypesAt(0).contains("text/plain"), 90 "text/plain exists in mozTypesAt" 91 ); 92 is( 93 dt.getData("text/plain"), 94 "Alternate", 95 "text/plain returned in getData" 96 ); 97 is( 98 dt.mozGetDataAt("text/plain", 0), 99 "Alternate", 100 "text/plain returned in mozGetDataAt" 101 ); 102 103 ok( 104 dt.mozTypesAt(0).contains("application/x-moz-file"), 105 "application/x-moz-file exists in mozTypesAt" 106 ); 107 let mozFile = dt.mozGetDataAt("application/x-moz-file", 0); 108 109 ok( 110 mozFile instanceof Ci.nsIFile, 111 "application/x-moz-file returned nsIFile with mozGetDataAt" 112 ); 113 114 is( 115 mozFile.leafName, 116 PathUtils.filename(file), 117 "nsIFile has correct leafName" 118 ); 119 120 resolve(); 121 }, 122 { capture: true, once: true } 123 ); 124 125 EventUtils.synthesizeKey("v", { accelKey: true }); 126 }); 127 128 input.remove(); 129 130 BrowserTestUtils.removeTab(tab); 131 132 await IOUtils.remove(file); 133 });