From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- ...e_on_editable_state_change_in_remote_content.js | 297 +++++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 widget/tests/browser/browser_test_ime_state_on_editable_state_change_in_remote_content.js (limited to 'widget/tests/browser/browser_test_ime_state_on_editable_state_change_in_remote_content.js') diff --git a/widget/tests/browser/browser_test_ime_state_on_editable_state_change_in_remote_content.js b/widget/tests/browser/browser_test_ime_state_on_editable_state_change_in_remote_content.js new file mode 100644 index 0000000000..8c38f97b72 --- /dev/null +++ b/widget/tests/browser/browser_test_ime_state_on_editable_state_change_in_remote_content.js @@ -0,0 +1,297 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* import-globals-from ../file_ime_state_test_helper.js */ + +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/widget/tests/browser/file_ime_state_test_helper.js", + this +); +add_task(async function () { + await BrowserTestUtils.withNewTab( + "https://example.com/browser/toolkit/content/tests/browser/file_empty.html", + async function (browser) { + const tipWrapper = new TIPWrapper(window); + ok( + tipWrapper.isAvailable(), + "TextInputProcessor should've been initialized" + ); + + await SpecialPowers.spawn(browser, [], () => { + content.wrappedJSObject.waitForIMEContentObserverSendingNotifications = + () => { + return new content.window.Promise(resolve => + content.window.requestAnimationFrame(() => + content.window.requestAnimationFrame(resolve) + ) + ); + }; + content.wrappedJSObject.resetIMEStateWithFocusMove = () => { + const input = content.document.createElement("input"); + content.document.body.appendChild(input); + input.focus(); + input.remove(); + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }; + content.document.body.innerHTML = "
"; + }); + + function resetIMEStateWithFocusMove() { + return SpecialPowers.spawn(browser, [], () => { + const input = content.document.createElement("input"); + content.document.body.appendChild(input); + input.focus(); + input.remove(); + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }); + } + + await (async function test_setting_contenteditable_of_focused_div() { + await SpecialPowers.spawn(browser, [], () => { + const div = content.document.querySelector("div"); + div.setAttribute("tabindex", "0"); + div.focus(); + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }); + is( + window.windowUtils.IMEStatus, + Ci.nsIDOMWindowUtils.IME_STATUS_DISABLED, + "test_setting_contenteditable_of_focused_div: IME should be disabled when non-editable
has focus" + ); + await SpecialPowers.spawn(browser, [], () => { + content.document + .querySelector("div") + .setAttribute("contenteditable", ""); + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }); + is( + window.windowUtils.IMEStatus, + Ci.nsIDOMWindowUtils.IME_STATUS_ENABLED, + "test_setting_contenteditable_of_focused_div: IME should be enabled when contenteditable of focused
is set" + ); + ok( + tipWrapper.IMEHasFocus, + "test_setting_contenteditable_of_focused_div: IME should have focus when contenteditable of focused
is set" + ); + await SpecialPowers.spawn(browser, [], () => { + content.document + .querySelector("div") + .removeAttribute("contenteditable"); + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }); + is( + window.windowUtils.IMEStatus, + Ci.nsIDOMWindowUtils.IME_STATUS_DISABLED, + "test_setting_contenteditable_of_focused_div: IME should be disabled when contenteditable of focused
is removed" + ); + ok( + !tipWrapper.IMEHasFocus, + "test_setting_contenteditable_of_focused_div: IME should not have focus when contenteditable of focused
is removed" + ); + await SpecialPowers.spawn(browser, [], () => { + content.document.querySelector("div").removeAttribute("tabindex"); + }); + })(); + + await resetIMEStateWithFocusMove(); + + await (async function test_removing_contenteditable_of_non_last_editable_div() { + await SpecialPowers.spawn(browser, [], async () => { + const div = content.document.querySelector("div"); + div.setAttribute("tabindex", "0"); + div.setAttribute("contenteditable", ""); + const anotherEditableDiv = content.document.createElement("div"); + anotherEditableDiv.setAttribute("contenteditable", ""); + div.parentElement.appendChild(anotherEditableDiv); + div.focus(); + await content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + div.removeAttribute("contenteditable"); + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }); + is( + window.windowUtils.IMEStatus, + Ci.nsIDOMWindowUtils.IME_STATUS_DISABLED, + "test_removing_contenteditable_of_non_last_editable_div: IME should be disabled when contenteditable of focused
is removed" + ); + ok( + !tipWrapper.IMEHasFocus, + "test_removing_contenteditable_of_non_last_editable_div: IME should not have focus when contenteditable of focused
is removed" + ); + await SpecialPowers.spawn(browser, [], () => { + const divs = content.document.querySelectorAll("div"); + divs[1].remove(); + divs[0].removeAttribute("tabindex"); + }); + })(); + + await resetIMEStateWithFocusMove(); + + await (async function test_setting_designMode() { + await SpecialPowers.spawn(browser, [], () => { + content.window.focus(); + content.document.designMode = "on"; + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }); + is( + window.windowUtils.IMEStatus, + Ci.nsIDOMWindowUtils.IME_STATUS_ENABLED, + 'test_setting_designMode: IME should be enabled when designMode is set to "on"' + ); + ok( + tipWrapper.IMEHasFocus, + 'test_setting_designMode: IME should have focus when designMode is set to "on"' + ); + await SpecialPowers.spawn(browser, [], () => { + content.document.designMode = "off"; + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }); + is( + window.windowUtils.IMEStatus, + Ci.nsIDOMWindowUtils.IME_STATUS_DISABLED, + 'test_setting_designMode: IME should be disabled when designMode is set to "off"' + ); + ok( + !tipWrapper.IMEHasFocus, + 'test_setting_designMode: IME should not have focus when designMode is set to "off"' + ); + })(); + + await resetIMEStateWithFocusMove(); + + async function test_setting_content_editable_of_body_when_shadow_DOM_has_focus( + aMode + ) { + await SpecialPowers.spawn(browser, [aMode], mode => { + const div = content.document.querySelector("div"); + const shadow = div.attachShadow({ mode }); + content.wrappedJSObject.divInShadow = + content.document.createElement("div"); + content.wrappedJSObject.divInShadow.setAttribute("tabindex", "0"); + shadow.appendChild(content.wrappedJSObject.divInShadow); + content.wrappedJSObject.divInShadow.focus(); + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }); + is( + window.windowUtils.IMEStatus, + Ci.nsIDOMWindowUtils.IME_STATUS_DISABLED, + `test_setting_content_editable_of_body_when_shadow_DOM_has_focus(${aMode}): IME should be disabled when non-editable
in a shadow DOM has focus` + ); + await SpecialPowers.spawn(browser, [], () => { + content.document.body.setAttribute("contenteditable", ""); + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }); + // todo_is because of bug 1807597. Gecko does not update focus when focused + // element becomes an editable child. Therefore, cannot initialize + // HTMLEditor with the new editing host. + todo_is( + window.windowUtils.IMEStatus, + Ci.nsIDOMWindowUtils.IME_STATUS_ENABLED, + `test_setting_content_editable_of_body_when_shadow_DOM_has_focus(${aMode}): IME should be enabled when the becomes editable` + ); + todo( + tipWrapper.IMEHasFocus, + `test_setting_content_editable_of_body_when_shadow_DOM_has_focus(${aMode}): IME should have focus when the becomes editable` + ); + await SpecialPowers.spawn(browser, [], () => { + content.document.body.removeAttribute("contenteditable"); + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }); + is( + window.windowUtils.IMEStatus, + Ci.nsIDOMWindowUtils.IME_STATUS_DISABLED, + `test_setting_content_editable_of_body_when_shadow_DOM_has_focus)${aMode}): IME should be disabled when the becomes not editable` + ); + ok( + !tipWrapper.IMEHasFocus, + `test_setting_content_editable_of_body_when_shadow_DOM_has_focus)${aMode}): IME should not have focus when the becomes not editable` + ); + await SpecialPowers.spawn(browser, [], () => { + content.document.querySelector("div").remove(); + content.document.body.appendChild( + content.document.createElement("div") + ); + }); + } + + async function test_setting_designMode_when_shadow_DOM_has_focus(aMode) { + await SpecialPowers.spawn(browser, [aMode], mode => { + const div = content.document.querySelector("div"); + const shadow = div.attachShadow({ mode }); + content.wrappedJSObject.divInShadow = + content.document.createElement("div"); + content.wrappedJSObject.divInShadow.setAttribute("tabindex", "0"); + shadow.appendChild(content.wrappedJSObject.divInShadow); + content.wrappedJSObject.divInShadow.focus(); + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }); + is( + window.windowUtils.IMEStatus, + Ci.nsIDOMWindowUtils.IME_STATUS_DISABLED, + `test_setting_designMode_when_shadow_DOM_has_focus(${aMode}): IME should be disabled when non-editable
in a shadow DOM has focus` + ); + await SpecialPowers.spawn(browser, [], () => { + content.document.designMode = "on"; + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }); + is( + window.windowUtils.IMEStatus, + Ci.nsIDOMWindowUtils.IME_STATUS_DISABLED, + `test_setting_designMode_when_shadow_DOM_has_focus(${aMode}): IME should stay disabled when designMode is set` + ); + ok( + !tipWrapper.IMEHasFocus, + `test_setting_designMode_when_shadow_DOM_has_focus(${aMode}): IME should not have focus when designMode is set` + ); + await SpecialPowers.spawn(browser, [], () => { + content.wrappedJSObject.divInShadow.setAttribute( + "contenteditable", + "" + ); + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }); + // todo_is because of bug 1807597. Gecko does not update focus when focused + // document is into the design mode. Therefore, cannot initialize + // HTMLEditor with the document node properly. + todo_is( + window.windowUtils.IMEStatus, + Ci.nsIDOMWindowUtils.IME_STATUS_ENABLED, + `test_setting_designMode_when_shadow_DOM_has_focus(${aMode}): IME should be enabled when focused
in a shadow DOM becomes editable` + ); + todo( + tipWrapper.IMEHasFocus, + `test_setting_designMode_when_shadow_DOM_has_focus(${aMode}): IME should have focus when focused
in a shadow DOM becomes editable` + ); + await SpecialPowers.spawn(browser, [], () => { + content.document.designMode = "off"; + return content.wrappedJSObject.waitForIMEContentObserverSendingNotifications(); + }); + is( + window.windowUtils.IMEStatus, + Ci.nsIDOMWindowUtils.IME_STATUS_DISABLED, + `test_setting_designMode_when_shadow_DOM_has_focus(${aMode}): IME should be disabled when designMode is unset` + ); + ok( + !tipWrapper.IMEHasFocus, + `test_setting_designMode_when_shadow_DOM_has_focus(${aMode}): IME should not have focus when designMode is unset` + ); + await SpecialPowers.spawn(browser, [], () => { + content.document.querySelector("div").remove(); + content.document.body.appendChild( + content.document.createElement("div") + ); + }); + } + + for (const mode of ["open", "closed"]) { + await test_setting_content_editable_of_body_when_shadow_DOM_has_focus( + mode + ); + await resetIMEStateWithFocusMove(); + await test_setting_designMode_when_shadow_DOM_has_focus(mode); + await resetIMEStateWithFocusMove(); + } + } + ); +}); -- cgit v1.2.3