diff options
Diffstat (limited to 'dom/events/test/clipboard')
-rw-r--r-- | dom/events/test/clipboard/browser_navigator_clipboard_contextmenu_suppression.js | 163 |
1 files changed, 156 insertions, 7 deletions
diff --git a/dom/events/test/clipboard/browser_navigator_clipboard_contextmenu_suppression.js b/dom/events/test/clipboard/browser_navigator_clipboard_contextmenu_suppression.js index f504e499c9..97066cd2eb 100644 --- a/dom/events/test/clipboard/browser_navigator_clipboard_contextmenu_suppression.js +++ b/dom/events/test/clipboard/browser_navigator_clipboard_contextmenu_suppression.js @@ -238,16 +238,10 @@ add_task(async function test_context_menu_suppression_image() { await pasteButtonIsShown; info("Test read from same-origin frame before paste contextmenu is closed"); - const clipboarCacheEnabled = SpecialPowers.getBoolPref( - "widget.clipboard.use-cached-data.enabled", - false - ); // If the cached data is used, it uses type order in cached transferable. SimpleTest.isDeeply( await readTypes(browser.browsingContext.children[0]), - clipboarCacheEnabled - ? ["text/plain", "text/html", "image/png"] - : ["text/html", "text/plain", "image/png"], + ["text/html", "text/plain", "image/png"], "read from same-origin should just be resolved without showing paste contextmenu shown" ); @@ -262,3 +256,158 @@ add_task(async function test_context_menu_suppression_image() { ); }); }); + +function testPasteContextMenuSuppressionPasteEvent( + aTriggerPasteFun, + aSuppress, + aMsg +) { + add_task(async function test_context_menu_suppression_paste_event() { + await BrowserTestUtils.withNewTab( + kContentFileUrl, + async function (browser) { + info(`Write data by in cross-origin frame`); + const clipboardText = "X" + Math.random(); + await SpecialPowers.spawn( + browser.browsingContext.children[1], + [clipboardText], + async text => { + content.document.notifyUserGestureActivation(); + return content.eval(`navigator.clipboard.writeText("${text}");`); + } + ); + + info("Test read should show contextmenu"); + let pasteButtonIsShown = waitForPasteContextMenu(); + let readTextRequest = readText(browser); + await pasteButtonIsShown; + + info("Click paste button, request should be resolved"); + await promiseClickPasteButton(); + is(await readTextRequest, clipboardText, "Request should be resolved"); + + info("Test read in paste event handler"); + readTextRequest = SpecialPowers.spawn(browser, [], async () => { + content.document.notifyUserGestureActivation(); + return content.eval(` + (() => { + return new Promise(resolve => { + document.addEventListener("paste", function(e) { + e.preventDefault(); + resolve(navigator.clipboard.readText()); + }, { once: true }); + }); + })(); + `); + }); + + if (aSuppress) { + let listener = function (e) { + if (e.target.getAttribute("id") == kPasteMenuPopupId) { + ok(!aSuppress, "paste contextmenu should not be shown"); + } + }; + document.addEventListener("popupshown", listener); + info(`Trigger paste event by ${aMsg}`); + // trigger paste event + await aTriggerPasteFun(browser); + is( + await readTextRequest, + clipboardText, + "Request should be resolved" + ); + document.removeEventListener("popupshown", listener); + } else { + let pasteButtonIsShown = waitForPasteContextMenu(); + info( + `Trigger paste event by ${aMsg}, read should still show contextmenu` + ); + // trigger paste event + await aTriggerPasteFun(browser); + await pasteButtonIsShown; + + info("Click paste button, request should be resolved"); + await promiseClickPasteButton(); + is( + await readTextRequest, + clipboardText, + "Request should be resolved" + ); + } + + info("Test read should still show contextmenu"); + pasteButtonIsShown = waitForPasteContextMenu(); + readTextRequest = readText(browser); + await pasteButtonIsShown; + + info("Click paste button, request should be resolved"); + await promiseClickPasteButton(); + is(await readTextRequest, clipboardText, "Request should be resolved"); + } + ); + }); +} + +// If platform supports selection clipboard, the middle click paste the content +// from selection clipboard instead, in such case, we don't suppress the +// contextmenu when access global clipboard via async clipboard API. +if ( + !Services.clipboard.isClipboardTypeSupported( + Services.clipboard.kSelectionClipboard + ) +) { + testPasteContextMenuSuppressionPasteEvent( + async browser => { + await SpecialPowers.pushPrefEnv({ + set: [["middlemouse.paste", true]], + }); + + await SpecialPowers.spawn(browser, [], async () => { + EventUtils.synthesizeMouse( + content.document.documentElement, + 1, + 1, + { button: 1 }, + content.window + ); + }); + }, + true, + "middle click" + ); +} + +testPasteContextMenuSuppressionPasteEvent( + async browser => { + await EventUtils.synthesizeAndWaitKey( + "v", + kIsMac ? { accelKey: true } : { ctrlKey: true } + ); + }, + true, + "keyboard shortcut" +); + +testPasteContextMenuSuppressionPasteEvent( + async browser => { + await SpecialPowers.spawn(browser, [], async () => { + return SpecialPowers.doCommand(content.window, "cmd_paste"); + }); + }, + true, + "paste command" +); + +testPasteContextMenuSuppressionPasteEvent( + async browser => { + await SpecialPowers.spawn(browser, [], async () => { + let div = content.document.createElement("div"); + div.setAttribute("contenteditable", "true"); + content.document.documentElement.appendChild(div); + div.focus(); + return SpecialPowers.doCommand(content.window, "cmd_pasteNoFormatting"); + }); + }, + false, + "pasteNoFormatting command" +); |