browser_document_command_cut.js (11682B)
1 /* -*- Mode: JavaScript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 "use strict"; 8 9 const kContentFileUrl = kBaseUrlForContent + "simple_page_ext.html"; 10 11 // https://bugzilla.mozilla.org/show_bug.cgi?id=1170911 12 [true, false].forEach(aPrefValue => { 13 describe(`dom.allow_cut_copy=${aPrefValue}`, () => { 14 it("set preference", async () => { 15 await SpecialPowers.pushPrefEnv({ 16 set: [["dom.allow_cut_copy", aPrefValue]], 17 }); 18 }); 19 20 it(`called from system principal`, () => { 21 document.clearUserGestureActivation(); 22 23 // Test without editing. 24 ok( 25 document.queryCommandSupported("cut"), 26 "Check if the 'cut' command is supported" 27 ); 28 // XXX: should "cut" command be disabled without an editing target, 29 // even if it is called from system principal? 30 ok( 31 document.queryCommandEnabled("cut"), 32 "Check if the 'cut' command is enabled without editing" 33 ); 34 // XXX: Should the "cut" command succeed even without an editable target 35 // when it’s called from the system principal? 36 ok( 37 document.execCommand("cut"), 38 "Check if the 'cut' command is succeed without editing" 39 ); 40 41 // Test with editing. 42 const textArea = document.createElement("textarea"); 43 document.body.appendChild(textArea); 44 textArea.textContent = "textarea text"; 45 textArea.setSelectionRange(0, textArea.value.length); 46 textArea.focus(); 47 ok( 48 document.queryCommandEnabled("cut"), 49 "Check if the 'cut' command is enabled when editing" 50 ); 51 ok( 52 document.execCommand("cut"), 53 "Check if the 'cut' command is succeed when editing" 54 ); 55 textArea.remove(); 56 }); 57 58 it(`called from web content`, async () => { 59 await BrowserTestUtils.withNewTab(kContentFileUrl, async browser => { 60 await SpecialPowers.spawn(browser, [aPrefValue], async aPrefValue => { 61 const doc = Cu.waiveXrays(content.document); 62 is( 63 doc.queryCommandSupported("cut"), 64 aPrefValue, 65 `Check if the 'cut' command is supported` 66 ); 67 68 // https://bugzilla.mozilla.org/show_bug.cgi?id=1012662 69 // Test no user activation. 70 content.document.clearUserGestureActivation(); 71 ok( 72 !doc.queryCommandEnabled("cut"), 73 "Check if the 'cut' command is enabled without user activation" 74 ); 75 ok( 76 !doc.execCommand("cut"), 77 "Check if the 'cut' command is succeed without user activation" 78 ); 79 80 // Test with user activation. 81 // XXX: should "cut" command be disabled without an editing target? 82 content.document.notifyUserGestureActivation(); 83 is( 84 doc.queryCommandEnabled("cut"), 85 aPrefValue, 86 "Check if the 'cut' command is enabled with user activation" 87 ); 88 ok( 89 !doc.execCommand("cut"), 90 "Check if the 'cut' command is succeed with user activation" 91 ); 92 93 // Test with editing. 94 const textArea = content.document.createElement("textarea"); 95 content.document.body.appendChild(textArea); 96 textArea.textContent = "textarea text"; 97 textArea.setSelectionRange(0, textArea.value.length); 98 textArea.focus(); 99 100 // Test no user activation. 101 content.document.clearUserGestureActivation(); 102 ok( 103 !doc.queryCommandEnabled("cut"), 104 "Check if the 'cut' command is enabled without user activation when editing" 105 ); 106 ok( 107 !doc.execCommand("cut"), 108 "Check if the 'cut' command is succeed without user activation when editing" 109 ); 110 111 // Test with user activation. 112 textArea.textContent = "textarea text"; 113 textArea.setSelectionRange(0, textArea.value.length); 114 textArea.focus(); 115 content.document.notifyUserGestureActivation(); 116 is( 117 doc.queryCommandEnabled("cut"), 118 aPrefValue, 119 "Check if the 'cut' command is enabled with user activation when editing" 120 ); 121 is( 122 doc.execCommand("cut"), 123 aPrefValue, 124 "Check if the 'cut' command is succeed with user activation when editing" 125 ); 126 }); 127 }); 128 }); 129 130 [true, false].forEach(aPermission => { 131 describe(`extension ${aPermission ? "with" : "without"} clipboardWrite permission`, () => { 132 const sharedScript = function () { 133 this.testCutCommand = function () { 134 return [ 135 document.queryCommandSupported("cut"), 136 document.queryCommandEnabled("cut"), 137 document.execCommand("cut"), 138 ]; 139 }; 140 }; 141 142 it("called from content script", async () => { 143 const contentScript = function () { 144 document 145 .querySelector("button") 146 .addEventListener("click", function (e) { 147 browser.test.sendMessage("result", testCutCommand()); 148 }); 149 browser.test.sendMessage("ready", testCutCommand()); 150 }; 151 const extensionData = { 152 manifest: { 153 content_scripts: [ 154 { 155 js: ["sharedScript.js", "contentscript.js"], 156 matches: ["https://example.com/*"], 157 }, 158 ], 159 }, 160 files: { 161 "sharedScript.js": sharedScript, 162 "contentscript.js": contentScript, 163 }, 164 }; 165 if (aPermission) { 166 extensionData.manifest.permissions = ["clipboardWrite"]; 167 } 168 169 // Load and start the extension. 170 const extension = ExtensionTestUtils.loadExtension(extensionData); 171 await extension.startup(); 172 await BrowserTestUtils.withNewTab(kContentFileUrl, async browser => { 173 let [supported, enabled, succeed] = 174 await extension.awaitMessage("ready"); 175 is( 176 supported, 177 aPrefValue || aPermission, 178 "Check if the 'cut' command is supported" 179 ); 180 181 // Test with user activation. 182 // XXX: should "cut" command be disabled without an editing target? 183 is( 184 enabled, 185 aPermission, 186 "Check if the 'cut' command is enabled without user activation" 187 ); 188 ok( 189 !succeed, 190 "Check if the 'cut' command is succeed without user activation" 191 ); 192 193 // Click on the content to trigger user activation. 194 promiseClickContentElement(browser, "btn"); 195 [supported, enabled, succeed] = 196 await extension.awaitMessage("result"); 197 // XXX: should "cut" command be disabled without an editing target? 198 is( 199 enabled, 200 aPrefValue || aPermission, 201 "Check if the 'cut' command is enabled with user activation" 202 ); 203 ok( 204 !succeed, 205 "Check if the 'cut' command is succeed with user activation" 206 ); 207 }); 208 await extension.unload(); 209 }); 210 211 it("called from content script when editing", async () => { 212 const contentScript = function () { 213 const textArea = document.createElement("textarea"); 214 document.body.appendChild(textArea); 215 const testCutCommandWhenEditing = function () { 216 // Start editing. 217 textArea.textContent = "textarea text"; 218 textArea.setSelectionRange(0, textArea.value.length); 219 textArea.focus(); 220 return testCutCommand(); 221 }; 222 document 223 .querySelector("button") 224 .addEventListener("click", function (e) { 225 browser.test.sendMessage("result", testCutCommandWhenEditing()); 226 }); 227 browser.test.sendMessage("ready", testCutCommandWhenEditing()); 228 }; 229 const extensionData = { 230 manifest: { 231 content_scripts: [ 232 { 233 js: ["sharedScript.js", "contentscript.js"], 234 matches: ["https://example.com/*"], 235 }, 236 ], 237 }, 238 files: { 239 "sharedScript.js": sharedScript, 240 "contentscript.js": contentScript, 241 }, 242 }; 243 if (aPermission) { 244 extensionData.manifest.permissions = ["clipboardWrite"]; 245 } 246 247 // Load and start the extension. 248 const extension = ExtensionTestUtils.loadExtension(extensionData); 249 await extension.startup(); 250 await BrowserTestUtils.withNewTab(kContentFileUrl, async browser => { 251 let [supported, enabled, succeed] = 252 await extension.awaitMessage("ready"); 253 is( 254 supported, 255 aPrefValue || aPermission, 256 "Check if the 'cut' command is supported" 257 ); 258 259 // Test with user activation. 260 is( 261 enabled, 262 aPermission, 263 "Check if the 'cut' command is enabled without user activation" 264 ); 265 is( 266 succeed, 267 aPermission, 268 "Check if the 'cut' command is succeed without user activation" 269 ); 270 271 // Click on the content to trigger user activation. 272 promiseClickContentElement(browser, "btn"); 273 [supported, enabled, succeed] = 274 await extension.awaitMessage("result"); 275 is( 276 enabled, 277 aPrefValue || aPermission, 278 "Check if the 'cut' command is enabled with user activation" 279 ); 280 is( 281 succeed, 282 aPrefValue || aPermission, 283 "Check if the 'cut' command is succeed with user activation" 284 ); 285 }); 286 await extension.unload(); 287 }); 288 289 it("called from background script", async () => { 290 const backgroundScript = function () { 291 browser.test.sendMessage("ready", testCutCommand()); 292 }; 293 const extensionData = { 294 background: [sharedScript, backgroundScript], 295 }; 296 if (aPermission) { 297 extensionData.manifest = { 298 permissions: ["clipboardWrite"], 299 }; 300 } 301 302 // Load and start the extension. 303 const extension = ExtensionTestUtils.loadExtension(extensionData); 304 await extension.startup(); 305 await BrowserTestUtils.withNewTab(kContentFileUrl, async browser => { 306 let [supported, enabled, succeed] = 307 await extension.awaitMessage("ready"); 308 is( 309 supported, 310 aPrefValue || aPermission, 311 "Check if the 'cut' command is supported" 312 ); 313 // XXX: should "cut" command be disabled without an editing target? 314 is(enabled, aPermission, "Check if the 'cut' command is enabled"); 315 ok(!succeed, "Check if the 'cut' command is succeed"); 316 }); 317 await extension.unload(); 318 }); 319 }); 320 }); 321 }); 322 });