diff options
Diffstat (limited to 'widget/tests')
25 files changed, 502 insertions, 88 deletions
diff --git a/widget/tests/browser/browser_test_clipboard_contextmenu.js b/widget/tests/browser/browser_test_clipboard_contextmenu.js index 4d268d5be4..80e8c33282 100644 --- a/widget/tests/browser/browser_test_clipboard_contextmenu.js +++ b/widget/tests/browser/browser_test_clipboard_contextmenu.js @@ -63,7 +63,7 @@ async function clipboardAsyncGetData(aBrowser, aClipboardType) { "nsIAsyncClipboardGetCallback", ]), // nsIAsyncClipboardGetCallback - onSuccess: aAsyncGetClipboardData => { + onSuccess: () => { resolve(); }, onError: aResult => { diff --git a/widget/tests/browser/browser_test_clipboardcache.js b/widget/tests/browser/browser_test_clipboardcache.js index 8cb6adb8b5..64deb99608 100644 --- a/widget/tests/browser/browser_test_clipboardcache.js +++ b/widget/tests/browser/browser_test_clipboardcache.js @@ -103,6 +103,10 @@ async function testCopyPaste(isPrivate) { document.execCommand("paste"); return pastePromise; }); + + // Don't use Assert.strictEqual here because the test starts timing out, + // because the logging creates lots of copies of this very huge string. + // eslint-disable-next-line mozilla/no-comparison-or-assignment-inside-ok ok(readStr === Ipsum, "Read what we pasted"); if (isPrivate) { diff --git a/widget/tests/browser/browser_test_swipe_gesture.js b/widget/tests/browser/browser_test_swipe_gesture.js index 0ac85d80c8..0f45672206 100644 --- a/widget/tests/browser/browser_test_swipe_gesture.js +++ b/widget/tests/browser/browser_test_swipe_gesture.js @@ -123,9 +123,9 @@ add_task(async () => { computedOpacity = window .getComputedStyle(gHistorySwipeAnimation._prevBox) .getPropertyValue("opacity"); - ok(computedOpacity == 1, "computed opacity of prevbox is 1"); + Assert.equal(computedOpacity, 1, "computed opacity of prevbox is 1"); opacity = gHistorySwipeAnimation._prevBox.style.opacity; - ok(opacity == 0, "element.style opacity of prevbox 0"); + Assert.equal(opacity, 0, "element.style opacity of prevbox 0"); if (isTranslatingIcon) { // We don't have a transition for translate property so that we still have @@ -232,9 +232,9 @@ add_task(async () => { computedOpacity = window .getComputedStyle(gHistorySwipeAnimation._prevBox) .getPropertyValue("opacity"); - ok(computedOpacity == 1, "computed opacity of prevbox is 1"); + Assert.equal(computedOpacity, 1, "computed opacity of prevbox is 1"); opacity = gHistorySwipeAnimation._prevBox.style.opacity; - ok(opacity == 0, "element.style opacity of prevbox 0"); + Assert.equal(opacity, 0, "element.style opacity of prevbox 0"); // Make sure the gesture triggered going back to the previous page. await Promise.all([startLoadingPromise, stoppedLoadingPromise]); @@ -317,9 +317,9 @@ add_task(async () => { let computedOpacity = window .getComputedStyle(gHistorySwipeAnimation._prevBox) .getPropertyValue("opacity"); - ok(computedOpacity == 1, "computed opacity of prevbox is 1"); + Assert.equal(computedOpacity, 1, "computed opacity of prevbox is 1"); let opacity = gHistorySwipeAnimation._prevBox.style.opacity; - ok(opacity == 0, "element.style opacity of prevbox 0"); + Assert.equal(opacity, 0, "element.style opacity of prevbox 0"); // Make sure the gesture triggered going back to the previous page. await Promise.all([startLoadingPromise, stoppedLoadingPromise]); @@ -343,7 +343,7 @@ add_task(async () => { } numTries--; } - ok(numTries > 0, "never ran the test"); + Assert.greater(numTries, 0, "never ran the test"); await SpecialPowers.popPrefEnv(); }); @@ -576,7 +576,7 @@ add_task(async () => { await panLeftToRightBegin(tab.linkedBrowser, 100, 100, 100); - ok(gHistorySwipeAnimation._prevBox != null, "should have prevbox"); + Assert.notEqual(gHistorySwipeAnimation._prevBox, null, "should have prevbox"); let transitionCancelPromise = new Promise(resolve => { gHistorySwipeAnimation._prevBox.addEventListener( "transitioncancel", @@ -635,7 +635,7 @@ add_task(async () => { await panRightToLeftBegin(tab.linkedBrowser, 100, 100, 100); - ok(gHistorySwipeAnimation._nextBox != null, "should have nextbox"); + Assert.notEqual(gHistorySwipeAnimation._nextBox, null, "should have nextbox"); transitionCancelPromise = new Promise(resolve => { gHistorySwipeAnimation._nextBox.addEventListener( "transitioncancel", @@ -1131,7 +1131,7 @@ add_task(async () => { // Set up an APZ aware event listener and... await SpecialPowers.spawn(tab.linkedBrowser, [], async () => { - content.document.documentElement.addEventListener("wheel", e => {}, { + content.document.documentElement.addEventListener("wheel", () => {}, { passive: false, }); await content.wrappedJSObject.promiseApzFlushedRepaints(); diff --git a/widget/tests/chrome.toml b/widget/tests/chrome.toml index 08d02d3c36..8706a67185 100644 --- a/widget/tests/chrome.toml +++ b/widget/tests/chrome.toml @@ -9,9 +9,6 @@ support-files = [ # Privacy relevant -["test_bug1123480.xhtml"] -skip-if = ["win11_2009 && bits == 32"] - ["test_bug343416.xhtml"] skip-if = ["debug"] @@ -66,8 +63,8 @@ run-if = ["os == 'mac'"] # Cocoa widget test ["test_bug760802.xhtml"] -["test_clipboard_chrome.html"] -support-files = "file_test_clipboard.js" +["test_bug1123480.xhtml"] +skip-if = ["win11_2009 && bits == 32"] ["test_clipboard_asyncGetData_chrome.html"] support-files = "file_test_clipboard_asyncGetData.js" @@ -77,11 +74,20 @@ support-files = "file_test_clipboard_asyncSetData.js" ["test_clipboard_cache_chrome.html"] +["test_clipboard_chrome.html"] +support-files = "file_test_clipboard.js" + +["test_clipboard_getDataSnapshotSync_chrome.html"] +support-files = "file_test_clipboard_getDataSnapshotSync.js" + ["test_clipboard_owner_chrome.html"] ["test_composition_text_querycontent.xhtml"] support-files = ["window_composition_text_querycontent.xhtml"] +["test_ime_focus_with_multiple_contenteditable.html"] +support-files = ["file_ime_state_test_helper.js"] + ["test_ime_state_in_contenteditable_on_readonly_change_in_parent.html"] support-files = [ "file_ime_state_test_helper.js", diff --git a/widget/tests/clipboard_helper.js b/widget/tests/clipboard_helper.js index 96787468fb..76ed2aeb37 100644 --- a/widget/tests/clipboard_helper.js +++ b/widget/tests/clipboard_helper.js @@ -157,11 +157,21 @@ function getClipboardData(aFlavor, aClipboardType) { } } -function asyncGetClipboardData(aClipboardType) { +function getClipboardDataSnapshotSync(aClipboardType) { + return clipboard.getDataSnapshotSync( + ["text/plain", "text/html", "image/png"], + aClipboardType + ); +} + +function asyncGetClipboardData( + aClipboardType, + aFormats = ["text/plain", "text/html", "image/png"] +) { return new Promise((resolve, reject) => { try { clipboard.asyncGetData( - ["text/plain", "text/html", "image/png"], + aFormats, aClipboardType, null, SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal(), diff --git a/widget/tests/file_test_clipboard_asyncGetData.js b/widget/tests/file_test_clipboard_asyncGetData.js index e7f2e5f0f1..3ff5700e1a 100644 --- a/widget/tests/file_test_clipboard_asyncGetData.js +++ b/widget/tests/file_test_clipboard_asyncGetData.js @@ -94,7 +94,7 @@ clipboardTypes.forEach(function (type) { () => { ok(false, "asyncClipboardRequestGetData should not success"); }, - e => { + () => { ok(true, "asyncClipboardRequestGetData should reject"); } ); @@ -133,7 +133,7 @@ clipboardTypes.forEach(function (type) { () => { ok(false, "asyncClipboardRequestGetData should not success"); }, - e => { + () => { ok(true, "asyncClipboardRequestGetData should reject"); } ); diff --git a/widget/tests/file_test_clipboard_getDataSnapshotSync.js b/widget/tests/file_test_clipboard_getDataSnapshotSync.js new file mode 100644 index 0000000000..92d7475e9c --- /dev/null +++ b/widget/tests/file_test_clipboard_getDataSnapshotSync.js @@ -0,0 +1,153 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* import-globals-from clipboard_helper.js */ + +"use strict"; + +clipboardTypes.forEach(function (type) { + if (!clipboard.isClipboardTypeSupported(type)) { + add_task(async function test_clipboard_requestGetData_not_support() { + info(`Test getDataSnapshotSync request throwing on ${type}`); + SimpleTest.doesThrow( + () => clipboard.getDataSnapshotSync(["text/plain"], type), + "Passing unsupported clipboard type should throw" + ); + }); + return; + } + + add_task(async function test_clipboard_getDataSnapshotSync_throw() { + info(`Test getDataSnapshotSync request throwing on ${type}`); + SimpleTest.doesThrow( + () => clipboard.getDataSnapshotSync([], type), + "Passing empty flavor list should throw" + ); + }); + + add_task( + async function test_clipboard_getDataSnapshotSync_no_matched_flavor() { + info(`Test getDataSnapshotSync have no matched flavor on ${type}`); + cleanupAllClipboard(); + is( + getClipboardData("text/plain", type), + null, + "ensure clipboard is empty" + ); + + writeRandomStringToClipboard("text/plain", type); + let request = clipboard.getDataSnapshotSync(["text/html"], type); + isDeeply(request.flavorList, [], "Check flavorList"); + } + ); + + add_task(async function test_empty_data() { + info(`Test getDataSnapshotSync request with empty data on ${type}`); + cleanupAllClipboard(); + is(getClipboardData("text/plain", type), null, "ensure clipboard is empty"); + + let request = getClipboardDataSnapshotSync(type); + isDeeply(request.flavorList, [], "Check flavorList"); + await asyncClipboardRequestGetData(request, "text/plain", true).catch( + () => {} + ); + }); + + add_task(async function test_clipboard_getDataSnapshotSync_after_write() { + info(`Test getDataSnapshotSync request after write on ${type}`); + + let str = writeRandomStringToClipboard("text/plain", type); + let request = getClipboardDataSnapshotSync(type); + isDeeply(request.flavorList, ["text/plain"], "Check flavorList"); + is( + await asyncClipboardRequestGetData(request, "text/plain"), + str, + "Check data" + ); + ok(request.valid, "request should still be valid"); + // Requesting a flavor that is not in the list should throw error. + await asyncClipboardRequestGetData(request, "text/html", true).catch( + () => {} + ); + ok(request.valid, "request should still be valid"); + + // Writing a new data should invalid existing get request. + str = writeRandomStringToClipboard("text/plain", type); + await asyncClipboardRequestGetData(request, "text/plain").then( + () => { + ok(false, "asyncClipboardRequestGetData should not success"); + }, + () => { + ok(true, "asyncClipboardRequestGetData should reject"); + } + ); + ok(!request.valid, "request should no longer be valid"); + + info(`check clipboard data again`); + request = getClipboardDataSnapshotSync(type); + isDeeply(request.flavorList, ["text/plain"], "Check flavorList"); + is( + await asyncClipboardRequestGetData(request, "text/plain"), + str, + "Check data" + ); + + cleanupAllClipboard(); + }); + + add_task(async function test_clipboard_getDataSnapshotSync_after_empty() { + info(`Test getDataSnapshotSync request after empty on ${type}`); + + let str = writeRandomStringToClipboard("text/plain", type); + let request = getClipboardDataSnapshotSync(type); + isDeeply(request.flavorList, ["text/plain"], "Check flavorList"); + is( + await asyncClipboardRequestGetData(request, "text/plain"), + str, + "Check data" + ); + ok(request.valid, "request should still be valid"); + + // Empty clipboard data + emptyClipboardData(type); + is(getClipboardData("text/plain", type), null, "ensure clipboard is empty"); + + await asyncClipboardRequestGetData(request, "text/plain").then( + () => { + ok(false, "asyncClipboardRequestGetData should not success"); + }, + () => { + ok(true, "asyncClipboardRequestGetData should reject"); + } + ); + ok(!request.valid, "request should no longer be valid"); + + info(`check clipboard data again`); + request = getClipboardDataSnapshotSync(type); + isDeeply(request.flavorList, [], "Check flavorList"); + + cleanupAllClipboard(); + }); +}); + +add_task(async function test_clipboard_getDataSnapshotSync_html_data() { + info(`Test getDataSnapshotSync request with html data`); + + const html_str = `<img src="https://example.com/oops">`; + writeStringToClipboard(html_str, "text/html", clipboard.kGlobalClipboard); + + let request = getClipboardDataSnapshotSync(clipboard.kGlobalClipboard); + isDeeply(request.flavorList, ["text/html"], "Check flavorList"); + is( + await asyncClipboardRequestGetData(request, "text/html"), + // On Windows, widget adds extra data into HTML clipboard. + navigator.platform.includes("Win") + ? `<html><body>\n<!--StartFragment-->${html_str}<!--EndFragment-->\n</body>\n</html>` + : html_str, + "Check data" + ); + // Requesting a flavor that is not in the list should throw error. + await asyncClipboardRequestGetData(request, "text/plain", true).catch( + () => {} + ); +}); diff --git a/widget/tests/mochitest.toml b/widget/tests/mochitest.toml index 32dcf5c795..4a4a9d2729 100644 --- a/widget/tests/mochitest.toml +++ b/widget/tests/mochitest.toml @@ -25,12 +25,16 @@ skip-if = [ support-files = ["file_test_clipboard.js"] ["test_clipboard_asyncGetData.html"] -skip-if = ["display == 'wayland'"] # Bug 1864211 +skip-if = ["display == 'wayland'"] # Bug 1879835 support-files = ["file_test_clipboard_asyncGetData.js"] ["test_clipboard_asyncSetData.html"] support-files = ["file_test_clipboard_asyncSetData.js"] +["test_clipboard_getDataSnapshotSync.html"] +skip-if = ["display == 'wayland'"] # Bug 1879835 +support-files = "file_test_clipboard_getDataSnapshotSync.js" + ["test_contextmenu_by_mouse_on_unix.html"] run-if = ["os == 'linux'"] skip-if = ["headless"] # headless widget doesn't dispatch contextmenu event by mouse event. diff --git a/widget/tests/standalone_native_menu_window.xhtml b/widget/tests/standalone_native_menu_window.xhtml index 4155126ad5..36c65b0e2c 100644 --- a/widget/tests/standalone_native_menu_window.xhtml +++ b/widget/tests/standalone_native_menu_window.xhtml @@ -141,13 +141,13 @@ let popupShowingFired = false; let itemActivated = false; - menupopup.addEventListener("popupshowing", function (e) { + menupopup.addEventListener("popupshowing", function () { popupShowingFired = true; let menuitem = document.createElementNS(XUL_NS, "menuitem"); menuitem.setAttribute("label", "detached menu item"); /* eslint-disable-next-line no-shadow */ - menuitem.addEventListener("command", function (e) { + menuitem.addEventListener("command", function () { itemActivated = true; }) menupopup.appendChild(menuitem); diff --git a/widget/tests/test_bug343416.xhtml b/widget/tests/test_bug343416.xhtml index bf4dbbb9b4..32e717d6e5 100644 --- a/widget/tests/test_bug343416.xhtml +++ b/widget/tests/test_bug343416.xhtml @@ -30,7 +30,7 @@ SimpleTest.waitForExplicitFinish(); var idleObserver = { QueryInterface: ChromeUtils.generateQI(["nsIObserver"]), - observe: function _observe(subject, topic, data) + observe: function _observe(subject, topic) { if (topic != "idle") return; diff --git a/widget/tests/test_clipboard_cache_chrome.html b/widget/tests/test_clipboard_cache_chrome.html index 55b6d41589..81d7a652b6 100644 --- a/widget/tests/test_clipboard_cache_chrome.html +++ b/widget/tests/test_clipboard_cache_chrome.html @@ -37,7 +37,12 @@ function testClipboardCache(aClipboardType, aAsync, aIsSupportGetFromCachedTrans addStringToTransferable("text/foo", string, trans); // XXX macOS caches the transferable to implement kSelectionCache type, too, // so it behaves differently than other types. - if (aClipboardType == clipboard.kSelectionCache && !aIsSupportGetFromCachedTransferable) { + if ( + navigator.platform.includes("Mac") && + aClipboardType == clipboard.kSelectionCache && + !aIsSupportGetFromCachedTransferable && + !SpecialPowers.isHeadless + ) { todo_is(getClipboardData("text/foo", aClipboardType), aIsSupportGetFromCachedTransferable ? string : null, `Check text/foo data on clipboard ${aClipboardType}`); @@ -66,7 +71,12 @@ function testClipboardCache(aClipboardType, aAsync, aIsSupportGetFromCachedTrans `Check text/plain data on clipboard ${aClipboardType} again`); // XXX macOS caches the transferable to implement kSelectionCache type, too, // so it behaves differently than other types. - if (aClipboardType == clipboard.kSelectionCache && !aIsSupportGetFromCachedTransferable) { + if ( + navigator.platform.includes("Mac") && + aClipboardType == clipboard.kSelectionCache && + !aIsSupportGetFromCachedTransferable && + !SpecialPowers.isHeadless + ) { todo_is(getClipboardData("text/foo", aClipboardType), aIsSupportGetFromCachedTransferable ? string : null, `Check text/foo data on clipboard ${aClipboardType} again`); @@ -118,7 +128,12 @@ function runClipboardCacheTests(aIsSupportGetFromCachedTransferable) { `Check if there is text/plain flavor on clipboard ${type}`); // XXX macOS caches the transferable to implement kSelectionCache type, too, // so it behaves differently than other types. - if (type == clipboard.kSelectionCache && !aIsSupportGetFromCachedTransferable) { + if ( + navigator.platform.includes("Mac") && + type == clipboard.kSelectionCache && + !aIsSupportGetFromCachedTransferable && + !SpecialPowers.isHeadless + ) { todo_is(clipboard.hasDataMatchingFlavors(["text/foo"], type), aIsSupportGetFromCachedTransferable, `Check if there is text/foo flavor on clipboard ${type}`); @@ -147,7 +162,12 @@ function runClipboardCacheTests(aIsSupportGetFromCachedTransferable) { `Check if there is text/plain flavor on clipboard ${type}`); // XXX macOS caches the transferable to implement kSelectionCache type, too, // so it behaves differently than other types. - if (type == clipboard.kSelectionCache && !aIsSupportGetFromCachedTransferable) { + if ( + navigator.platform.includes("Mac") && + type == clipboard.kSelectionCache && + !aIsSupportGetFromCachedTransferable && + !SpecialPowers.isHeadless + ) { todo_is(clipboard.hasDataMatchingFlavors(["text/foo"], type), aIsSupportGetFromCachedTransferable, `Check if there is text/foo flavor on clipboard ${type}`); @@ -212,6 +232,33 @@ function runClipboardCacheTests(aIsSupportGetFromCachedTransferable) { await testClipboardData(await asyncGetClipboardData(type), clipboardData); }); + add_task(async function test_flavorList_order() { + info(`test_flavorList_order with pref ` + + `${aIsSupportGetFromCachedTransferable ? "enabled" : "disabled"}`); + + const trans = generateNewTransferable("text/plain", generateRandomString()); + addStringToTransferable("text/html", `<div>${generateRandomString()}</div>`, trans); + + info(`Writedata to clipboard ${type}`); + clipboard.setData(trans, null, type); + + // Read with reverse order. + let flavors = trans.flavorsTransferableCanExport().reverse(); + let request = await asyncGetClipboardData(type, flavors); + // XXX Not all clipboard type supports html format, e.g. kFindClipboard + // on macOS only support writing text/plain. + if ( + navigator.platform.includes("Mac") && + type == clipboard.kFindClipboard && + !aIsSupportGetFromCachedTransferable && + !SpecialPowers.isHeadless + ) { + isDeeply(request.flavorList, ["text/plain"], "check flavor orders"); + } else { + isDeeply(request.flavorList, flavors, "check flavor orders"); + } + }); + // Test sync set clipboard data. testClipboardCache(type, false, aIsSupportGetFromCachedTransferable); diff --git a/widget/tests/test_clipboard_getDataSnapshotSync.html b/widget/tests/test_clipboard_getDataSnapshotSync.html new file mode 100644 index 0000000000..e800f6a1b0 --- /dev/null +++ b/widget/tests/test_clipboard_getDataSnapshotSync.html @@ -0,0 +1,19 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1858627 +--> +<head> +<title>Test for Bug 1858627</title> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="clipboard_helper.js"></script> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +<!-- Tests are in file_test_clipboard_getDataSnapshotSync.js --> +<script src="file_test_clipboard_getDataSnapshotSync.js"></script> +</body> +</html> diff --git a/widget/tests/test_clipboard_getDataSnapshotSync_chrome.html b/widget/tests/test_clipboard_getDataSnapshotSync_chrome.html new file mode 100644 index 0000000000..fbc283ccb3 --- /dev/null +++ b/widget/tests/test_clipboard_getDataSnapshotSync_chrome.html @@ -0,0 +1,19 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1858627 +--> +<head> +<title>Test for Bug 1858627</title> +<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> +<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script src="clipboard_helper.js"></script> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +<!-- Tests are in file_test_clipboard_getDataSnapshotSync.js --> +<script src="file_test_clipboard_getDataSnapshotSync.js"></script> +</body> +</html> diff --git a/widget/tests/test_clipboard_owner_chrome.html b/widget/tests/test_clipboard_owner_chrome.html index 4759b2b14c..2991646616 100644 --- a/widget/tests/test_clipboard_owner_chrome.html +++ b/widget/tests/test_clipboard_owner_chrome.html @@ -20,7 +20,7 @@ function testClipboardOwner(aClipboardType, aAsync) { const clipboardOwner = { QueryInterface: ChromeUtils.generateQI(["nsIClipboardOwner"]), // nsIClipboardOwner - LosingOwnership(aTransferable) { + LosingOwnership() { losingOwnership = true; }, }; diff --git a/widget/tests/test_contextmenu_by_mouse_on_unix.html b/widget/tests/test_contextmenu_by_mouse_on_unix.html index 2b1f643dfc..04bca8116c 100644 --- a/widget/tests/test_contextmenu_by_mouse_on_unix.html +++ b/widget/tests/test_contextmenu_by_mouse_on_unix.html @@ -60,7 +60,7 @@ async function process_contextmenu_event({ isMousedown, preventEvent }) { is(count++, 1, "The second event is contextmenu"); e.preventDefault(); }, { once: true }); - target.addEventListener("mouseup", e => { + target.addEventListener("mouseup", () => { is(count++, 2, "The third event is mouseup"); resolve(); }, { once: true} ); diff --git a/widget/tests/test_ime_focus_with_multiple_contenteditable.html b/widget/tests/test_ime_focus_with_multiple_contenteditable.html new file mode 100644 index 0000000000..6b435a1a2e --- /dev/null +++ b/widget/tests/test_ime_focus_with_multiple_contenteditable.html @@ -0,0 +1,104 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1872863 +--> +<head> +<title>Test IME state and focus with multiple contenteditable elements</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + <script src="file_ime_state_test_helper.js"></script> +<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + +<style> +#div0 { + width: 200px; + height: 50px; +} + +#div3 { + background-color: blue; + width: 200px; + height: 100px; +} + +#div4 { + width: 200px; + height: 50px; +} +</style> +<script> +add_task(async function test_modify_contenteditable_on_focused_element() { + await SimpleTest.promiseFocus(); + + const tipWrapper = new TIPWrapper(window); + ok(tipWrapper.isAvailable(), "TextInputProcessor should've been initialized"); + + const div1 = document.getElementById("div1"); + const div2 = document.getElementById("div2"); + const div3 = document.getElementById("div3"); + + div1.addEventListener("mousedown", () => { + div2.contentEditable = true; + }); + div3.addEventListener("mousedown", e => { + div2.contentEditable = false; + e.preventDefault(); + }); + + // Set focus by mouse then contenteditable becomes true by script. + + const promiseFocus = new Promise(resolve => { + div2.addEventListener("focus", resolve, { once: true }); + }); + synthesizeMouseAtCenter(div1, {}); + await promiseFocus; + + is( + SpecialPowers.DOMWindowUtils.IMEStatus, + SpecialPowers.DOMWindowUtils.IME_STATUS_ENABLED, + "IMEStatus is enabled on contenteditable=true" + ); + ok(tipWrapper.IMEHasFocus, "IME has focus"); + + // Move focus by mouse then contenteditable becomes false by script. + + const promiseMouseUp = new Promise(resolve => { + div3.addEventListener("mouseup", resolve, { once: true }); + }); + synthesizeMouseAtCenter(div3, {}); + await promiseMouseUp; + + is( + SpecialPowers.DOMWindowUtils.IMEStatus, + SpecialPowers.DOMWindowUtils.IME_STATUS_DISABLED, + "IMEStatus is disabled on contenteditable=false" + ); + ok(!tipWrapper.IMEHasFocus, "IME losts focus after contenteditable=false"); + + // contenteditable changes to true on focused element. + + const promiseMouseUp2 = new Promise(resolve => { + div1.addEventListener("mouseup", resolve, { once: true }); + }); + synthesizeMouseAtCenter(div1, {}); + await promiseMouseUp2; + + is( + SpecialPowers.DOMWindowUtils.IMEStatus, + SpecialPowers.DOMWindowUtils.IME_STATUS_ENABLED, + "IMEStatus is enabled on contenteditable=true" + ); + + ok(tipWrapper.IMEHasFocus, "IME has focus after contenteditable=true again"); +}); +</script> +</head> +<body> +<div id="div0"><div id="div1"> +<div id="div2" contenteditable="false"><div>foo</div></div> +</div></div> +<div id="div3"></div> +<div id="div4" contenteditable></div> +</body> +</html> diff --git a/widget/tests/test_ime_state_others_in_parent.html b/widget/tests/test_ime_state_others_in_parent.html index e6ae0ab272..e71ef90556 100644 --- a/widget/tests/test_ime_state_others_in_parent.html +++ b/widget/tests/test_ime_state_others_in_parent.html @@ -96,7 +96,7 @@ function runTestPasswordFieldOnDialog() { WindowObserver.prototype = { QueryInterface: ChromeUtils.generateQI(["nsIObserver"]), - observe(subject, topic, data) { + observe(subject, topic) { if (topic === "domwindowopened") { ok(true, "dialog window is created"); dialog = subject; diff --git a/widget/tests/test_key_event_counts.xhtml b/widget/tests/test_key_event_counts.xhtml index 6eda6a52fb..e50164ddfd 100644 --- a/widget/tests/test_key_event_counts.xhtml +++ b/widget/tests/test_key_event_counts.xhtml @@ -24,7 +24,7 @@ var gKeyPressEventCount = 0; var gKeyDownEventCount = 0; - function onKeyDown(e) + function onKeyDown() { gKeyDownEventCount++; } diff --git a/widget/tests/test_keycodes.xhtml b/widget/tests/test_keycodes.xhtml index aea6aaae98..5adb07b4d8 100644 --- a/widget/tests/test_keycodes.xhtml +++ b/widget/tests/test_keycodes.xhtml @@ -519,14 +519,14 @@ function* runKeyEventTests() document.addEventListener("keypress", onKeyEvent); document.addEventListener("keyup", onKeyEvent); // Prevent almost all shortcut key handlers. - SpecialPowers.addSystemEventListener(document, "keypress", consumer, true); + SpecialPowers.wrap(document).addEventListener("keypress", consumer, { capture: true, mozSystemGroup: true }); function cleanup() { document.removeEventListener("keydown", onKeyEvent); document.removeEventListener("keypress", onKeyEvent); document.removeEventListener("keyup", onKeyEvent); - SpecialPowers.removeSystemEventListener(document, "keypress", consumer, true); + SpecialPowers.wrap(document).removeEventListener("keypress", consumer, { capture: true, mozSystemGroup: true }); } function* testKeysOnMac() @@ -4802,7 +4802,7 @@ function* runAccessKeyTests() var button = document.getElementById("button"); var activationCount; - function onClick(e) + function onClick() { ++activationCount; } @@ -4968,10 +4968,10 @@ function* runXULKeyTests() buttonParent.addEventListener("keypress", onKeyInDefaultEventGroup, true); buttonParent.addEventListener("keydown", onKeyInDefaultEventGroup); buttonParent.addEventListener("keypress", onKeyInDefaultEventGroup); - SpecialPowers.addSystemEventListener(buttonParent, "keydown", onKeyInSystemEventGroup, true); - SpecialPowers.addSystemEventListener(buttonParent, "keypress", onKeyInSystemEventGroup, true); - SpecialPowers.addSystemEventListener(buttonParent, "keydown", onKeyInSystemEventGroup, false); - SpecialPowers.addSystemEventListener(buttonParent, "keypress", onKeyInSystemEventGroup, false); + SpecialPowers.wrap(buttonParent).addEventListener("keydown", onKeyInSystemEventGroup, { capture: true, mozSystemGroup: true }); + SpecialPowers.wrap(buttonParent).addEventListener("keypress", onKeyInSystemEventGroup, { capture: true, mozSystemGroup: true }); + SpecialPowers.wrap(buttonParent).addEventListener("keydown", onKeyInSystemEventGroup, { capture: false, mozSystemGroup: true }); + SpecialPowers.wrap(buttonParent).addEventListener("keypress", onKeyInSystemEventGroup, { capture: false, mozSystemGroup: true }); function finializeKeyElementTest() { @@ -4979,10 +4979,10 @@ function* runXULKeyTests() buttonParent.removeEventListener("keypress", onKeyInDefaultEventGroup, true); buttonParent.removeEventListener("keydown", onKeyInDefaultEventGroup); buttonParent.removeEventListener("keypress", onKeyInDefaultEventGroup); - SpecialPowers.removeSystemEventListener(buttonParent, "keydown", onKeyInSystemEventGroup, true); - SpecialPowers.removeSystemEventListener(buttonParent, "keypress", onKeyInSystemEventGroup, true); - SpecialPowers.removeSystemEventListener(buttonParent, "keydown", onKeyInSystemEventGroup, false); - SpecialPowers.removeSystemEventListener(buttonParent, "keypress", onKeyInSystemEventGroup, false); + SpecialPowers.wrap(buttonParent).removeEventListener("keydown", onKeyInSystemEventGroup, { capture: true, mozSystemGroup: true }); + SpecialPowers.wrap(buttonParent).removeEventListener("keypress", onKeyInSystemEventGroup, { capture: true, mozSystemGroup: true }); + SpecialPowers.wrap(buttonParent).removeEventListener("keydown", onKeyInSystemEventGroup, { capture: false, mozSystemGroup: true }); + SpecialPowers.wrap(buttonParent).removeEventListener("keypress", onKeyInSystemEventGroup, { capture: false, mozSystemGroup: true }); } // If aKeyElement is empty string, this function tests if the event kicks @@ -5218,10 +5218,10 @@ function* runReservedKeyTests() contents[i].addEventListener("keypress", onKeyInDefaultEventGroup, true); contents[i].addEventListener("keydown", onKeyInDefaultEventGroup); contents[i].addEventListener("keypress", onKeyInDefaultEventGroup); - SpecialPowers.addSystemEventListener(contents[i], "keydown", onKeyInSystemEventGroup, true); - SpecialPowers.addSystemEventListener(contents[i], "keypress", onKeyInSystemEventGroup, true); - SpecialPowers.addSystemEventListener(contents[i], "keydown", onKeyInSystemEventGroup, false); - SpecialPowers.addSystemEventListener(contents[i], "keypress", onKeyInSystemEventGroup, false); + SpecialPowers.wrap(contents[i]).addEventListener("keydown", onKeyInSystemEventGroup, { capture: true, mozSystemGroup: true }); + SpecialPowers.wrap(contents[i]).addEventListener("keypress", onKeyInSystemEventGroup, { capture: true, mozSystemGroup: true }); + SpecialPowers.wrap(contents[i]).addEventListener("keydown", onKeyInSystemEventGroup, { capture: false, mozSystemGroup: true }); + SpecialPowers.wrap(contents[i]).addEventListener("keypress", onKeyInSystemEventGroup, { capture: false, mozSystemGroup: true }); } var keyEvents = []; @@ -5256,10 +5256,10 @@ function* runReservedKeyTests() contents[i].removeEventListener("keypress", onKeyInDefaultEventGroup, true); contents[i].removeEventListener("keydown", onKeyInDefaultEventGroup); contents[i].removeEventListener("keypress", onKeyInDefaultEventGroup); - SpecialPowers.removeSystemEventListener(contents[i], "keydown", onKeyInSystemEventGroup, true); - SpecialPowers.removeSystemEventListener(contents[i], "keypress", onKeyInSystemEventGroup, true); - SpecialPowers.removeSystemEventListener(contents[i], "keydown", onKeyInSystemEventGroup, false); - SpecialPowers.removeSystemEventListener(contents[i], "keypress", onKeyInSystemEventGroup, false); + SpecialPowers.wrap(contents[i]).removeEventListener("keydown", onKeyInSystemEventGroup, { capture: true, mozSystemGroup: true }); + SpecialPowers.wrap(contents[i]).removeEventListener("keypress", onKeyInSystemEventGroup, { capture: true, mozSystemGroup: true }); + SpecialPowers.wrap(contents[i]).removeEventListener("keydown", onKeyInSystemEventGroup, { capture: false, mozSystemGroup: true }); + SpecialPowers.wrap(contents[i]).removeEventListener("keypress", onKeyInSystemEventGroup, { capture: false, mozSystemGroup: true }); } } diff --git a/widget/tests/test_native_key_bindings_mac.html b/widget/tests/test_native_key_bindings_mac.html index 8767a5a77d..81a13aea0e 100644 --- a/widget/tests/test_native_key_bindings_mac.html +++ b/widget/tests/test_native_key_bindings_mac.html @@ -292,7 +292,7 @@ aElement.id + ": Incorrect selection end"); } - function* testRun(aElement, aSelectionCheck, aCallback) { + function* testRun(aElement, aSelectionCheck) { if (document.activeElement) { document.activeElement.blur(); } diff --git a/widget/tests/test_sizemode_events.xhtml b/widget/tests/test_sizemode_events.xhtml index bd1e3a38d1..c1224fbf70 100644 --- a/widget/tests/test_sizemode_events.xhtml +++ b/widget/tests/test_sizemode_events.xhtml @@ -31,7 +31,7 @@ const kAsyncChanges = kIsLinux || kIsMacOS; let gSizeModeDidChange = false; let gSizeModeDidChangeTo = 0; -function sizemodeChanged(e) { +function sizemodeChanged() { gSizeModeDidChange = true; gSizeModeDidChangeTo = gWindow.windowState; } diff --git a/widget/tests/window_bug478536.xhtml b/widget/tests/window_bug478536.xhtml index 7318eb0bff..206226ec74 100644 --- a/widget/tests/window_bug478536.xhtml +++ b/widget/tests/window_bug478536.xhtml @@ -177,7 +177,7 @@ function fireWheelScrollEvent(aForward) }, window); } -function onScrollView(aEvent) +function onScrollView() { if (gIgnoreScrollEvent) return; @@ -187,7 +187,7 @@ function onScrollView(aEvent) gTimer = setTimeout(runNextTest, 0); } -function onMouseScrollFailed(aEvent) +function onMouseScrollFailed() { clearTimer(); gIgnoreScrollEvent = true; @@ -197,7 +197,7 @@ function onMouseScrollFailed(aEvent) runNextTest(); } -function onTransactionTimeout(aEvent) +function onTransactionTimeout() { if (!gTimer) return; diff --git a/widget/tests/window_composition_text_querycontent.xhtml b/widget/tests/window_composition_text_querycontent.xhtml index db3b10ea30..4806d0d187 100644 --- a/widget/tests/window_composition_text_querycontent.xhtml +++ b/widget/tests/window_composition_text_querycontent.xhtml @@ -6270,7 +6270,7 @@ function runQueryContentEventRelativeToInsertionPoint() synthesizeComposition({ type: "compositioncommitasis" }); // Move start of composition at first compositionupdate event. - function onCompositionUpdate(aEvent) + function onCompositionUpdate() { startOffset = textarea.selectionStart = textarea.selectionEnd = textarea.selectionStart - 1; textarea.removeEventListener("compositionupdate", onCompositionUpdate); diff --git a/widget/tests/window_imestate_iframes.html b/widget/tests/window_imestate_iframes.html index c8b182977f..3c2d0908ae 100644 --- a/widget/tests/window_imestate_iframes.html +++ b/widget/tests/window_imestate_iframes.html @@ -49,6 +49,8 @@ function onUnload() { var gFocusObservingElement = null; var gBlurObservingElement = null; +var canTabMoveFocusToRootElement = + !SpecialPowers.getBoolPref("dom.disable_tab_focus_to_root_element"); function onFocus(aEvent) { if (aEvent.target != gFocusObservingElement) { @@ -201,18 +203,30 @@ function runTests() { root = iframe.contentDocument.documentElement; resetFocusToInput("initializing for iframe_not_editable"); - testTabKey(true, root, false, prev, true, - false, "input#prev[readonly] -> html"); - testTabKey(true, editor, true, root, false, - true, "html -> input in the subdoc"); + if (canTabMoveFocusToRootElement) { + testTabKey(true, root, false, prev, true, + false, "input#prev[readonly] -> html"); + testTabKey(true, editor, true, root, false, + true, "html -> input in the subdoc"); + } else { + testTabKey(true, editor, true, prev, true, + true, "input#prev[readonly] -> input in the subdoc"); + } testTabKey(true, next, true, editor, true, false, "input in the subdoc -> input#next[readonly]"); testTabKey(false, editor, true, next, true, true, "input#next[readonly] -> input in the subdoc"); - testTabKey(false, root, false, editor, true, - false, "input in the subdoc -> html"); - testTabKey(false, prev, true, root, false, - false, "html -> input#next[readonly]"); + if (canTabMoveFocusToRootElement) { + testTabKey(false, root, false, editor, true, + false, "input in the subdoc -> html"); + testTabKey(false, prev, true, root, false, + false, "html -> input#next[readonly]"); + } else { + testTabKey(false, prev, true, editor, true, + false, "input in the subdoc -> input#prev[readonly]"); + testTabKey(false, next, true, prev, true, + false, "input#prev[readonly] -> input#next[readonly]"); + } iframe.style.display = "none"; @@ -236,8 +250,13 @@ function runTests() { resetFocusToParentHTML("testing iframe_html"); testTabKey(true, editor, true, html, false, true, "html of parent -> html[contentediable=true]"); - testTabKey(false, html, false, editor, true, - false, "html[contenteditable=true] -> html of parent"); + if (canTabMoveFocusToRootElement) { + testTabKey(false, html, false, editor, true, + false, "html[contenteditable=true] -> html of parent"); + } else { + testTabKey(false, next, true, editor, true, + false, "html[contenteditable=true] -> input#next[readonly]"); + } prev.style.display = "inline"; resetFocusToInput("after parent html <-> html[contenteditable=true]"); @@ -270,8 +289,13 @@ function runTests() { resetFocusToParentHTML("testing iframe_designMode"); testTabKey(true, root, false, html, false, true, "html of parent -> html in designMode"); - testTabKey(false, html, false, root, false, - false, "html in designMode -> html of parent"); + if (canTabMoveFocusToRootElement) { + testTabKey(false, html, false, root, false, + false, "html[contenteditable=true] -> html of parent"); + } else { + testTabKey(false, next, true, root, false, + false, "html in designMode -> html of parent"); + } prev.style.display = "inline"; resetFocusToInput("after parent html <-> html in designMode"); @@ -302,8 +326,13 @@ function runTests() { resetFocusToParentHTML("testing iframe_body"); testTabKey(true, editor, true, html, false, true, "html of parent -> body[contentediable=true]"); - testTabKey(false, html, false, editor, true, - false, "body[contenteditable=true] -> html of parent"); + if (canTabMoveFocusToRootElement) { + testTabKey(false, html, false, editor, true, + false, "body[contenteditable=true] -> html of parent"); + } else { + testTabKey(false, next, true, editor, true, + false, "body[contenteditable=true] -> input#next[readonly]"); + } prev.style.display = "inline"; resetFocusToInput("after parent html <-> body[contenteditable=true]"); @@ -321,25 +350,44 @@ function runTests() { root = iframe.contentDocument.documentElement; resetFocusToInput("initializing for iframe_p"); - testTabKey(true, root, false, prev, true, - false, "input#prev[readonly] -> html (has p[contenteditable=true])"); - testTabKey(true, editor, true, root, false, - true, "html (has p[contenteditable=true]) -> p[contentediable=true]"); + if (canTabMoveFocusToRootElement) { + testTabKey(true, root, false, prev, true, + false, "input#prev[readonly] -> html (has p[contenteditable=true])"); + testTabKey(true, editor, true, root, false, + true, "html (has p[contenteditable=true]) -> p[contentediable=true]"); + } else { + testTabKey(true, editor, true, prev, true, + true, "input#prev[readonly] -> p[contenteditable=true]"); + } testTabKey(true, next, true, editor, true, false, "p[contentediable=true] -> input#next[readonly]"); testTabKey(false, editor, true, next, true, true, "input#next[readonly] -> p[contentediable=true]"); - testTabKey(false, root, false, editor, true, - false, "p[contenteditable=true] -> html (has p[contenteditable=true])"); - testTabKey(false, prev, true, root, false, - false, "html (has p[contenteditable=true]) -> input#prev[readonly]"); + if (canTabMoveFocusToRootElement) { + testTabKey(false, root, false, editor, true, + false, "p[contenteditable=true] -> html (has p[contenteditable=true])"); + testTabKey(false, prev, true, root, false, + false, "html (has p[contenteditable=true]) -> input#prev[readonly]"); + } else { + testTabKey(false, prev, true, editor, true, + false, "p[contenteditable=true] -> html (has p[contenteditable=true])"); + testTabKey(false, next, true, prev, true, + false, "html (has p[contenteditable=true]) -> input#next[readonly]"); + } prev.style.display = "none"; resetFocusToParentHTML("testing iframe_p"); - testTabKey(true, root, false, html, false, - false, "html of parent -> html (has p[contentediable=true])"); - testTabKey(false, html, false, root, false, - false, "html (has p[contentediable=true]) -> html of parent"); + if (canTabMoveFocusToRootElement) { + testTabKey(true, root, false, html, false, + false, "html of parent -> html (has p[contentediable=true])"); + testTabKey(false, html, false, root, false, + false, "html (has p[contentediable=true]) -> html of parent"); + } else { + testTabKey(true, editor, true, html, false, + true, "html of parent -> p[contentediable=true]"); + testTabKey(false, next, true, editor, true, + false, "p[contentediable=true] -> input#next[readonly]"); + } prev.style.display = "inline"; resetFocusToInput("after parent html <-> html (has p[contentediable=true])"); diff --git a/widget/tests/window_mouse_scroll_win.html b/widget/tests/window_mouse_scroll_win.html index bf90abb1b5..48ccc1fed4 100644 --- a/widget/tests/window_mouse_scroll_win.html +++ b/widget/tests/window_mouse_scroll_win.html @@ -214,7 +214,7 @@ var gPreparingSteps = [ target: gP1, x: 10, y: 10, window, modifiers: 0, additionalFlags: 0, - onLineScrollEvent(aEvent) { + onLineScrollEvent() { return true; }, onPixelScrollEvent(aEvent) { @@ -234,7 +234,7 @@ var gPreparingSteps = [ target: gP1, x: 10, y: 10, window, modifiers: 0, additionalFlags: 0, - onLineScrollEvent(aEvent) { + onLineScrollEvent() { return true; }, onPixelScrollEvent(aEvent) { @@ -250,7 +250,7 @@ var gPreparingSteps = [ target: gP1, x: 10, y: 10, window, modifiers: 0, additionalFlags: 0, - onLineScrollEvent(aEvent) { + onLineScrollEvent() { return true; }, onPixelScrollEvent(aEvent) { @@ -270,7 +270,7 @@ var gPreparingSteps = [ target: gP1, x: 10, y: 10, window, modifiers: 0, additionalFlags: 0, - onLineScrollEvent(aEvent) { + onLineScrollEvent() { return true; }, onPixelScrollEvent(aEvent) { @@ -1100,7 +1100,7 @@ var gDeactiveWindowTests = [ SpecialPowers.setIntPref(kVAmountPref, 3); SpecialPowers.setIntPref(kHAmountPref, 3); }, - onLineScrollEvent(aEvent) { + onLineScrollEvent() { var fm = Services.focus; is(fm.activeWindow, gOtherWindow, "The other window isn't activated"); }, |