зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1481923 - Make nsContentUtils::SendMouseEvent return the information where preventDefault() was called. r=masayuki
On a long press touch event we fire a contextmenu event and if the contextmenu is opening, we fire a touchcancel event. Unfortunately we had been checking the return value, nsEventStatus, from nsIWidget::DispatchInputEvent via nsContentUtils::SendMouseEvent to tell whether the context menu is opening or not. So, we unintentionally fire the touchcancel event if the context menu is NOT going to be opened because of preventDefault() in a contextmenu event listener in the content itself. NOTE: The oparator<< for the new PreventDefaultResult enum will be used in APZ logging code. [1] https://searchfox.org/mozilla-central/rev/95c41d54c3fd65d51976d5188842a69b459a7589/mobile/android/actors/ContentDelegateChild.jsm#100 Differential Revision: https://phabricator.services.mozilla.com/D115963
This commit is contained in:
Родитель
1ba472c91b
Коммит
aafeee2434
|
@ -8196,7 +8196,7 @@ nsresult nsContentUtils::SendMouseEvent(
|
|||
int32_t aButton, int32_t aButtons, int32_t aClickCount, int32_t aModifiers,
|
||||
bool aIgnoreRootScrollFrame, float aPressure,
|
||||
unsigned short aInputSourceArg, uint32_t aIdentifier, bool aToWindow,
|
||||
bool* aPreventDefault, bool aIsDOMEventSynthesized,
|
||||
PreventDefaultResult* aPreventDefault, bool aIsDOMEventSynthesized,
|
||||
bool aIsWidgetEventSynthesized) {
|
||||
nsPoint offset;
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget(aPresShell, &offset);
|
||||
|
@ -8278,7 +8278,15 @@ nsresult nsContentUtils::SendMouseEvent(
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
if (aPreventDefault) {
|
||||
*aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
|
||||
if (status == nsEventStatus_eConsumeNoDefault) {
|
||||
if (event.mFlags.mDefaultPreventedByContent) {
|
||||
*aPreventDefault = PreventDefaultResult::ByContent;
|
||||
} else {
|
||||
*aPreventDefault = PreventDefaultResult::ByChrome;
|
||||
}
|
||||
} else {
|
||||
*aPreventDefault = PreventDefaultResult::No;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -10602,3 +10610,21 @@ nsCString nsContentUtils::TruncatedURLForDisplay(nsIURI* aURL,
|
|||
}
|
||||
return spec;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
std::ostream& operator<<(std::ostream& aOut,
|
||||
const PreventDefaultResult aPreventDefaultResult) {
|
||||
switch (aPreventDefaultResult) {
|
||||
case PreventDefaultResult::No:
|
||||
aOut << "unhandled";
|
||||
break;
|
||||
case PreventDefaultResult::ByContent:
|
||||
aOut << "handled-by-content";
|
||||
break;
|
||||
case PreventDefaultResult::ByChrome:
|
||||
aOut << "handled-by-chrome";
|
||||
break;
|
||||
}
|
||||
return aOut;
|
||||
}
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -245,6 +245,10 @@ struct EventNameMapping {
|
|||
bool mMaybeSpecialSVGorSMILEvent;
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
enum class PreventDefaultResult : uint8_t { No, ByContent, ByChrome };
|
||||
}
|
||||
|
||||
class nsContentUtils {
|
||||
friend class nsAutoScriptBlockerSuppressNodeRemoved;
|
||||
typedef mozilla::dom::Element Element;
|
||||
|
@ -2916,8 +2920,8 @@ class nsContentUtils {
|
|||
float aY, int32_t aButton, int32_t aButtons, int32_t aClickCount,
|
||||
int32_t aModifiers, bool aIgnoreRootScrollFrame, float aPressure,
|
||||
unsigned short aInputSourceArg, uint32_t aIdentifier, bool aToWindow,
|
||||
bool* aPreventDefault, bool aIsDOMEventSynthesized,
|
||||
bool aIsWidgetEventSynthesized);
|
||||
mozilla::PreventDefaultResult* aPreventDefault,
|
||||
bool aIsDOMEventSynthesized, bool aIsWidgetEventSynthesized);
|
||||
|
||||
static void FirePageShowEventForFrameLoaderSwap(
|
||||
nsIDocShellTreeItem* aItem,
|
||||
|
@ -3492,6 +3496,12 @@ nsContentUtils::InternalContentPolicyTypeToExternal(nsContentPolicyType aType) {
|
|||
}
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
std::ostream& operator<<(
|
||||
std::ostream& aOut,
|
||||
const mozilla::PreventDefaultResult aPreventDefaultResult);
|
||||
} // namespace mozilla
|
||||
|
||||
class MOZ_RAII nsAutoScriptBlocker {
|
||||
public:
|
||||
explicit nsAutoScriptBlocker() { nsContentUtils::AddScriptBlocker(); }
|
||||
|
|
|
@ -725,10 +725,17 @@ nsDOMWindowUtils::SendMouseEventCommon(
|
|||
bool aToWindow, bool* aPreventDefault, bool aIsDOMEventSynthesized,
|
||||
bool aIsWidgetEventSynthesized, int32_t aButtons) {
|
||||
RefPtr<PresShell> presShell = GetPresShell();
|
||||
return nsContentUtils::SendMouseEvent(
|
||||
PreventDefaultResult preventDefaultResult;
|
||||
nsresult rv = nsContentUtils::SendMouseEvent(
|
||||
presShell, aType, aX, aY, aButton, aButtons, aClickCount, aModifiers,
|
||||
aIgnoreRootScrollFrame, aPressure, aInputSourceArg, aPointerId, aToWindow,
|
||||
aPreventDefault, aIsDOMEventSynthesized, aIsWidgetEventSynthesized);
|
||||
&preventDefaultResult, aIsDOMEventSynthesized, aIsWidgetEventSynthesized);
|
||||
|
||||
if (aPreventDefault) {
|
||||
*aPreventDefault = preventDefaultResult != PreventDefaultResult::No;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -551,13 +551,14 @@ bool APZCCallbackHelper::DispatchMouseEvent(
|
|||
unsigned short aInputSourceArg, uint32_t aPointerId) {
|
||||
NS_ENSURE_TRUE(aPresShell, true);
|
||||
|
||||
bool defaultPrevented = false;
|
||||
PreventDefaultResult preventDefaultResult;
|
||||
nsContentUtils::SendMouseEvent(
|
||||
aPresShell, aType, aPoint.x, aPoint.y, aButton,
|
||||
nsIDOMWindowUtils::MOUSE_BUTTONS_NOT_SPECIFIED, aClickCount, aModifiers,
|
||||
/* aIgnoreRootScrollFrame = */ false, 0, aInputSourceArg, aPointerId,
|
||||
false, &defaultPrevented, false, /* aIsWidgetEventSynthesized = */ false);
|
||||
return defaultPrevented;
|
||||
false, &preventDefaultResult, false,
|
||||
/* aIsWidgetEventSynthesized = */ false);
|
||||
return preventDefaultResult != PreventDefaultResult::No;
|
||||
}
|
||||
|
||||
void APZCCallbackHelper::FireSingleTapEvent(const LayoutDevicePoint& aPoint,
|
||||
|
|
Загрузка…
Ссылка в новой задаче