Bug 1965183 - Consider to set microtask level to 0 when dispatching events, r=masayuki,webdriver-reviewers,whimboo

Differential Revision: https://phabricator.services.mozilla.com/D248391
This commit is contained in:
Olli Pettay
2025-05-17 07:42:45 +00:00
committed by opettay@mozilla.com
parent bfa5a1cc27
commit fa024d34a5
7 changed files with 47 additions and 12 deletions

View File

@@ -105,6 +105,7 @@
#include "nsIBaseWindow.h" #include "nsIBaseWindow.h"
#include "nsIDocShellTreeOwner.h" #include "nsIDocShellTreeOwner.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "nsContentPermissionHelper.h" #include "nsContentPermissionHelper.h"
#include "nsCSSPseudoElements.h" // for PseudoStyleType #include "nsCSSPseudoElements.h" // for PseudoStyleType
@@ -4986,3 +4987,19 @@ nsDOMWindowUtils::SendMozMouseHitTestEvent(float aX, float aY,
false /* aToWindow */, nullptr /* aPreventDefault */, false /* aToWindow */, nullptr /* aPreventDefault */,
true /* aIsDOMEventSynthesized */, true /* aIsWidgetEventSynthesized */); true /* aIsDOMEventSynthesized */, true /* aIsWidgetEventSynthesized */);
} }
NS_IMETHODIMP
nsDOMWindowUtils::GetMicroTaskLevel(uint32_t* aLevel) {
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
NS_ENSURE_STATE(ccjs);
*aLevel = ccjs->MicroTaskLevel();
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::SetMicroTaskLevel(uint32_t aLevel) {
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
NS_ENSURE_STATE(ccjs);
ccjs->SetMicroTaskLevel(aLevel);
return NS_OK;
}

View File

@@ -2355,6 +2355,10 @@ interface nsIDOMWindowUtils : nsISupports {
// The current drag session on this widget of this window (if any). // The current drag session on this widget of this window (if any).
readonly attribute nsIDragSession dragSession; readonly attribute nsIDragSession dragSession;
// Get/Set microtask level. If you don't know how microtasks work both in the
// specification and Gecko, please don't use this.
attribute unsigned long microTaskLevel;
}; };
[scriptable, uuid(c694e359-7227-4392-a138-33c0cc1f15a6)] [scriptable, uuid(c694e359-7227-4392-a138-33c0cc1f15a6)]

View File

@@ -71,6 +71,13 @@ export class MarionetteCommandsChild extends JSWindowActorChild {
const { eventName, details } = options; const { eventName, details } = options;
const win = this.contentWindow; const win = this.contentWindow;
const windowUtils = win.windowUtils;
const microTaskLevel = windowUtils.microTaskLevel;
// Since we're being called as a webidl callback,
// CallbackObjectBase::CallSetup::CallSetup has increased the microtask
// level. Undo that temporarily so that microtask handling works closer
// the way it would work when dispatching events natively.
windowUtils.microTaskLevel = 0;
try { try {
switch (eventName) { switch (eventName) {
case "synthesizeKeyDown": case "synthesizeKeyDown":
@@ -114,6 +121,8 @@ export class MarionetteCommandsChild extends JSWindowActorChild {
} }
throw e; throw e;
} finally {
windowUtils.microTaskLevel = microTaskLevel;
} }
} }

View File

@@ -52,6 +52,14 @@ class InputModule extends WindowGlobalBiDiModule {
async _dispatchEvent(options) { async _dispatchEvent(options) {
const { eventName, details } = options; const { eventName, details } = options;
const windowUtils = this.messageHandler.window.windowUtils;
const microTaskLevel = windowUtils.microTaskLevel;
// Since we're being called as a webidl callback,
// CallbackObjectBase::CallSetup::CallSetup has increased the microtask
// level. Undo that temporarily so that microtask handling works closer
// the way it would work when dispatching events natively.
windowUtils.microTaskLevel = 0;
try { try {
switch (eventName) { switch (eventName) {
case "synthesizeKeyDown": case "synthesizeKeyDown":
@@ -98,6 +106,8 @@ class InputModule extends WindowGlobalBiDiModule {
} }
throw e; throw e;
} finally {
windowUtils.microTaskLevel = microTaskLevel;
} }
} }

View File

@@ -1,15 +1,14 @@
[select-events-2.tentative.html] [select-events-2.tentative.html]
[Button controller code should not run if the mousedown event is preventDefaulted.]
expected: FAIL
[Listbox controller code should not run if the mousedown event is preventDefaulted.] [Listbox controller code should not run if the mousedown event is preventDefaulted.]
expected: FAIL expected:
if (os == "android"): FAIL
[<select> should fire input and change events when new option is selected.] [<select> should fire input and change events when new option is selected.]
expected: FAIL expected: FAIL
[<select> should not fire input and change events when new selected option has the same value as the old.] [<select> should not fire input and change events when new selected option has the same value as the old.]
expected: FAIL expected:
if (os == "android"): FAIL
[<select> should fire input and change events when option in listbox is clicked] [<select> should fire input and change events when option in listbox is clicked]
expected: FAIL expected: FAIL

View File

@@ -1,8 +1,3 @@
[pointerevent_boundary_events_in_capturing.html?touch]
[Boundary events around pointer capture and release]
expected: FAIL
[pointerevent_boundary_events_in_capturing.html?pen] [pointerevent_boundary_events_in_capturing.html?pen]
[Boundary events around pointer capture and release] [Boundary events around pointer capture and release]
expected: FAIL expected: FAIL

View File

@@ -1,4 +1,5 @@
[pointerevent_lostpointercapture_remove_setcapture_node.html] [pointerevent_lostpointercapture_remove_setcapture_node.html]
expected: ERROR expected: TIMEOUT
max-asserts: 1
[setPointerCapture target removed by lostpointercapture] [setPointerCapture target removed by lostpointercapture]
expected: FAIL expected: TIMEOUT