Backed out 3 changesets (bug 1851970) for causing mochitests failures in browser_aboutNetError_csp_iframe.js.
Backed out changeset a2536c6c6c23 (bug 1851970) Backed out changeset 23ddc229d1a1 (bug 1851970) Backed out changeset b99a620a535c (bug 1851970)
This commit is contained in:
@@ -3132,8 +3132,6 @@ void Element::GetEventTargetParentForLinks(EventChainPreVisitor& aVisitor) {
|
||||
case eFocus:
|
||||
case eMouseOut:
|
||||
case eBlur:
|
||||
case eMouseClick:
|
||||
case eLegacyDOMActivate:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@@ -3183,15 +3181,6 @@ void Element::GetEventTargetParentForLinks(EventChainPreVisitor& aVisitor) {
|
||||
break;
|
||||
}
|
||||
|
||||
case eLegacyDOMActivate:
|
||||
aVisitor.mWantsActivationBehavior = true;
|
||||
break;
|
||||
case eMouseClick:
|
||||
if (WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent()) {
|
||||
aVisitor.mWantsActivationBehavior = mouseEvent->IsLeftClickEvent();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// switch not in sync with the optimization switch earlier in this
|
||||
// function
|
||||
@@ -3242,7 +3231,9 @@ nsresult Element::PostHandleEventForLinks(EventChainPostVisitor& aVisitor) {
|
||||
// IMPORTANT: this switch and the switch below it must be kept in sync!
|
||||
switch (aVisitor.mEvent->mMessage) {
|
||||
case eMouseDown:
|
||||
case eMouseClick:
|
||||
case eMouseAuxClick:
|
||||
case eLegacyDOMActivate:
|
||||
case eKeyPress:
|
||||
break;
|
||||
default:
|
||||
@@ -3307,10 +3298,64 @@ nsresult Element::PostHandleEventForLinks(EventChainPostVisitor& aVisitor) {
|
||||
}
|
||||
} break;
|
||||
|
||||
case eMouseClick: {
|
||||
WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
|
||||
if (mouseEvent->IsLeftClickEvent()) {
|
||||
if (!mouseEvent->IsControl() && !mouseEvent->IsMeta() &&
|
||||
!mouseEvent->IsAlt() && !mouseEvent->IsShift()) {
|
||||
if (OwnerDoc()->MayHaveDOMActivateListeners()) {
|
||||
// The default action is simply to dispatch DOMActivate.
|
||||
// But dispatch that only if needed.
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
// DOMActivate event should be trusted since the activation is
|
||||
// actually occurred even if the cause is an untrusted click event.
|
||||
InternalUIEvent actEvent(true, eLegacyDOMActivate, mouseEvent);
|
||||
actEvent.mDetail = 1;
|
||||
rv = EventDispatcher::Dispatch(this, aVisitor.mPresContext,
|
||||
&actEvent, nullptr, &status);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
} else {
|
||||
if (nsCOMPtr<nsIURI> absURI = GetHrefURI()) {
|
||||
// If you modify this code, tweak also the code handling
|
||||
// eLegacyDOMActivate.
|
||||
nsAutoString target;
|
||||
GetLinkTarget(target);
|
||||
nsContentUtils::TriggerLink(this, absURI, target,
|
||||
/* click */ true,
|
||||
mouseEvent->IsTrusted());
|
||||
}
|
||||
// Since we didn't dispatch DOMActivate because there were no
|
||||
// listeners, do still set mEventStatus as if it was dispatched
|
||||
// successfully.
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
}
|
||||
|
||||
DispatchChromeOnlyLinkClickEvent(aVisitor);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case eMouseAuxClick: {
|
||||
DispatchChromeOnlyLinkClickEvent(aVisitor);
|
||||
break;
|
||||
}
|
||||
case eLegacyDOMActivate: {
|
||||
// If you modify this code, tweak also the code handling
|
||||
// eMouseClick.
|
||||
if (aVisitor.mEvent->mOriginalTarget == this) {
|
||||
if (nsCOMPtr<nsIURI> absURI = GetHrefURI()) {
|
||||
nsAutoString target;
|
||||
GetLinkTarget(target);
|
||||
const InternalUIEvent* activeEvent = aVisitor.mEvent->AsUIEvent();
|
||||
MOZ_ASSERT(activeEvent);
|
||||
nsContentUtils::TriggerLink(this, absURI, target, /* click */ true,
|
||||
activeEvent->IsTrustable());
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case eKeyPress: {
|
||||
WidgetKeyboardEvent* keyEvent = aVisitor.mEvent->AsKeyboardEvent();
|
||||
@@ -3334,61 +3379,6 @@ nsresult Element::PostHandleEventForLinks(EventChainPostVisitor& aVisitor) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
void Element::ActivationBehaviorForLinks(EventChainPostVisitor& aVisitor) {
|
||||
// Make sure we meet the preconditions before continuing
|
||||
if (!IsLink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aVisitor.mEvent->mMessage == eLegacyDOMActivate) {
|
||||
if (aVisitor.mEvent->mOriginalTarget != this) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
|
||||
MOZ_ASSERT(mouseEvent && mouseEvent->IsLeftClickEvent());
|
||||
DispatchChromeOnlyLinkClickEvent(aVisitor);
|
||||
|
||||
if (mouseEvent->IsControl() || mouseEvent->IsMeta() ||
|
||||
mouseEvent->IsAlt() || mouseEvent->IsShift()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (OwnerDoc()->MayHaveDOMActivateListeners()) {
|
||||
// The default action is simply to dispatch DOMActivate.
|
||||
// But dispatch that only if needed.
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
// DOMActivate event should be trusted since the activation is
|
||||
// actually occurred even if the cause is an untrusted click event.
|
||||
InternalUIEvent actEvent(true, eLegacyDOMActivate, mouseEvent);
|
||||
actEvent.mDetail = 1;
|
||||
nsresult rv = EventDispatcher::Dispatch(this, aVisitor.mPresContext,
|
||||
&actEvent, nullptr, &status);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool trusted;
|
||||
if (aVisitor.mEvent->mMessage == eLegacyDOMActivate) {
|
||||
const InternalUIEvent* activeEvent = aVisitor.mEvent->AsUIEvent();
|
||||
MOZ_ASSERT(activeEvent);
|
||||
trusted = activeEvent->IsTrustable();
|
||||
} else {
|
||||
trusted = aVisitor.mEvent->IsTrusted();
|
||||
}
|
||||
|
||||
if (nsCOMPtr<nsIURI> absURI = GetHrefURI()) {
|
||||
nsAutoString target;
|
||||
GetLinkTarget(target);
|
||||
nsContentUtils::TriggerLink(this, absURI, target, /* click */ true,
|
||||
trusted);
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
}
|
||||
|
||||
void Element::GetLinkTarget(nsAString& aTarget) { aTarget.Truncate(); }
|
||||
|
||||
static nsStaticAtom* const sPropertiesToTraverseAndUnlink[] = {
|
||||
|
||||
@@ -2035,12 +2035,6 @@ class Element : public FragmentOrElement {
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
nsresult PostHandleEventForLinks(EventChainPostVisitor& aVisitor);
|
||||
|
||||
/**
|
||||
* Handle activation behavior for link click event
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ActivationBehaviorForLinks(EventChainPostVisitor& aVisitor);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Check if this element is a link. This matches the CSS definition of the
|
||||
|
||||
@@ -146,10 +146,6 @@ nsresult HTMLAnchorElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
return PostHandleEventForAnchors(aVisitor);
|
||||
}
|
||||
|
||||
void HTMLAnchorElement::ActivationBehavior(EventChainPostVisitor& aVisitor) {
|
||||
ActivationBehaviorForAnchors(aVisitor);
|
||||
}
|
||||
|
||||
void HTMLAnchorElement::GetLinkTarget(nsAString& aTarget) {
|
||||
GetAttr(nsGkAtoms::target, aTarget);
|
||||
if (aTarget.IsEmpty()) {
|
||||
|
||||
@@ -56,8 +56,6 @@ class HTMLAnchorElement final : public nsGenericHTMLElement,
|
||||
void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override;
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ActivationBehavior(EventChainPostVisitor& aVisitor) override;
|
||||
|
||||
void GetLinkTarget(nsAString& aTarget) override;
|
||||
already_AddRefed<nsIURI> GetHrefURI() const override;
|
||||
|
||||
@@ -49,10 +49,6 @@ nsresult HTMLAreaElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
return PostHandleEventForAnchors(aVisitor);
|
||||
}
|
||||
|
||||
void HTMLAreaElement::ActivationBehavior(EventChainPostVisitor& aVisitor) {
|
||||
ActivationBehaviorForAnchors(aVisitor);
|
||||
}
|
||||
|
||||
void HTMLAreaElement::GetLinkTarget(nsAString& aTarget) {
|
||||
GetAttr(nsGkAtoms::target, aTarget);
|
||||
if (aTarget.IsEmpty()) {
|
||||
|
||||
@@ -41,8 +41,6 @@ class HTMLAreaElement final : public nsGenericHTMLElement,
|
||||
void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override;
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ActivationBehavior(EventChainPostVisitor& aVisitor) override;
|
||||
|
||||
void GetLinkTarget(nsAString& aTarget) override;
|
||||
already_AddRefed<nsIURI> GetHrefURI() const override;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "mozAutoDocUpdate.h"
|
||||
|
||||
#define NS_IN_SUBMIT_CLICK (1 << 0)
|
||||
#define NS_OUTER_ACTIVATE_EVENT (1 << 1)
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Button)
|
||||
|
||||
@@ -170,6 +171,7 @@ void HTMLButtonElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
|
||||
!mInInternalActivate && aVisitor.mEvent->mOriginalTarget == this));
|
||||
|
||||
if (outerActivateEvent) {
|
||||
aVisitor.mItemFlags |= NS_OUTER_ACTIVATE_EVENT;
|
||||
aVisitor.mWantsActivationBehavior = true;
|
||||
}
|
||||
|
||||
@@ -224,6 +226,14 @@ nsresult HTMLButtonElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
if (keyEvent && keyEvent->IsTrusted()) {
|
||||
HandleKeyboardActivation(aVisitor);
|
||||
}
|
||||
|
||||
// Bug 1459231: Temporarily needed till links respect activation target
|
||||
// Then also remove NS_OUTER_ACTIVATE_EVENT
|
||||
if ((aVisitor.mItemFlags & NS_OUTER_ACTIVATE_EVENT) && mForm &&
|
||||
(mType == FormControlType::ButtonReset ||
|
||||
mType == FormControlType::ButtonSubmit)) {
|
||||
aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
||||
@@ -131,15 +131,16 @@ NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Input)
|
||||
namespace mozilla::dom {
|
||||
|
||||
// First bits are needed for the control type.
|
||||
// (1 << 9 is unused)
|
||||
#define NS_OUTER_ACTIVATE_EVENT (1 << 9)
|
||||
#define NS_ORIGINAL_CHECKED_VALUE (1 << 10)
|
||||
// (1 << 11 is unused)
|
||||
#define NS_ORIGINAL_INDETERMINATE_VALUE (1 << 12)
|
||||
#define NS_PRE_HANDLE_BLUR_EVENT (1 << 13)
|
||||
#define NS_IN_SUBMIT_CLICK (1 << 15)
|
||||
#define NS_CONTROL_TYPE(bits) \
|
||||
((bits) & ~(NS_ORIGINAL_CHECKED_VALUE | NS_ORIGINAL_INDETERMINATE_VALUE | \
|
||||
NS_PRE_HANDLE_BLUR_EVENT | NS_IN_SUBMIT_CLICK))
|
||||
#define NS_CONTROL_TYPE(bits) \
|
||||
((bits) & ~(NS_OUTER_ACTIVATE_EVENT | NS_ORIGINAL_CHECKED_VALUE | \
|
||||
NS_ORIGINAL_INDETERMINATE_VALUE | NS_PRE_HANDLE_BLUR_EVENT | \
|
||||
NS_IN_SUBMIT_CLICK))
|
||||
|
||||
// whether textfields should be selected once focused:
|
||||
// -1: no, 1: yes, 0: uninitialized
|
||||
@@ -3121,6 +3122,9 @@ bool HTMLInputElement::CheckActivationBehaviorPreconditions(
|
||||
((mouseEvent && mouseEvent->IsLeftClickEvent()) ||
|
||||
(aVisitor.mEvent->mMessage == eLegacyDOMActivate &&
|
||||
!mInInternalActivate));
|
||||
if (outerActivateEvent) {
|
||||
aVisitor.mItemFlags |= NS_OUTER_ACTIVATE_EVENT;
|
||||
}
|
||||
return outerActivateEvent;
|
||||
}
|
||||
default:
|
||||
@@ -3986,6 +3990,16 @@ nsresult HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Bug 1459231: Temporarily needed till links respect activation target
|
||||
// Then also remove NS_OUTER_ACTIVATE_EVENT
|
||||
if ((aVisitor.mItemFlags & NS_OUTER_ACTIVATE_EVENT) &&
|
||||
(mType == FormControlType::InputReset ||
|
||||
mType == FormControlType::InputSubmit ||
|
||||
mType == FormControlType::InputImage) &&
|
||||
mForm) {
|
||||
aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
|
||||
}
|
||||
}
|
||||
} // if
|
||||
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
*/
|
||||
#include "HTMLLabelElement.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
#include "mozilla/dom/HTMLLabelElementBinding.h"
|
||||
#include "mozilla/dom/MouseEventBinding.h"
|
||||
#include "nsFocusManager.h"
|
||||
@@ -67,34 +65,17 @@ void HTMLLabelElement::Focus(const FocusOptions& aOptions,
|
||||
}
|
||||
}
|
||||
|
||||
bool HTMLLabelElement::CheckHandleEventPreconditions(
|
||||
EventChainVisitor& aVisitor) {
|
||||
return !mHandlingEvent &&
|
||||
aVisitor.mEventStatus != nsEventStatus_eConsumeDoDefault &&
|
||||
aVisitor.mPresContext &&
|
||||
!aVisitor.mEvent->mFlags.mMultipleActionsPrevented;
|
||||
}
|
||||
|
||||
void HTMLLabelElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
|
||||
WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
|
||||
|
||||
if (CheckHandleEventPreconditions(aVisitor) && mouseEvent &&
|
||||
mouseEvent->IsLeftClickEvent()) {
|
||||
aVisitor.mWantsActivationBehavior = true;
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::GetEventTargetParent(aVisitor);
|
||||
}
|
||||
|
||||
nsresult HTMLLabelElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
if (!CheckHandleEventPreconditions(aVisitor)) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (aVisitor.mEvent->mMessage != eMouseDown) {
|
||||
return NS_OK;
|
||||
}
|
||||
WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
|
||||
MOZ_ASSERT(mouseEvent);
|
||||
if (mHandlingEvent ||
|
||||
(!(mouseEvent && mouseEvent->IsLeftClickEvent()) &&
|
||||
aVisitor.mEvent->mMessage != eMouseDown) ||
|
||||
aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault ||
|
||||
!aVisitor.mPresContext ||
|
||||
// Don't handle the event if it's already been handled by another label
|
||||
aVisitor.mEvent->mFlags.mMultipleActionsPrevented) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<Element> target =
|
||||
do_QueryInterface(aVisitor.mEvent->GetOriginalDOMEventTarget());
|
||||
@@ -123,6 +104,72 @@ nsresult HTMLLabelElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
}
|
||||
break;
|
||||
|
||||
case eMouseClick:
|
||||
if (mouseEvent->IsLeftClickEvent()) {
|
||||
LayoutDeviceIntPoint* mouseDownPoint =
|
||||
static_cast<LayoutDeviceIntPoint*>(
|
||||
GetProperty(nsGkAtoms::labelMouseDownPtProperty));
|
||||
|
||||
bool dragSelect = false;
|
||||
if (mouseDownPoint) {
|
||||
LayoutDeviceIntPoint dragDistance = *mouseDownPoint;
|
||||
RemoveProperty(nsGkAtoms::labelMouseDownPtProperty);
|
||||
|
||||
dragDistance -= mouseEvent->mRefPoint;
|
||||
const int CLICK_DISTANCE = 2;
|
||||
dragSelect = dragDistance.x > CLICK_DISTANCE ||
|
||||
dragDistance.x < -CLICK_DISTANCE ||
|
||||
dragDistance.y > CLICK_DISTANCE ||
|
||||
dragDistance.y < -CLICK_DISTANCE;
|
||||
}
|
||||
// Don't click the for-content if we did drag-select text or if we
|
||||
// have a kbd modifier (which adjusts a selection).
|
||||
if (dragSelect || mouseEvent->IsShift() || mouseEvent->IsControl() ||
|
||||
mouseEvent->IsAlt() || mouseEvent->IsMeta()) {
|
||||
break;
|
||||
}
|
||||
// Only set focus on the first click of multiple clicks to prevent
|
||||
// to prevent immediate de-focus.
|
||||
if (mouseEvent->mClickCount <= 1) {
|
||||
if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
|
||||
// Use FLAG_BYMOVEFOCUS here so that the label is scrolled to.
|
||||
// Also, within HTMLInputElement::PostHandleEvent, inputs will
|
||||
// be selected only when focused via a key or when the navigation
|
||||
// flag is used and we want to select the text on label clicks as
|
||||
// well.
|
||||
// If the label has been clicked by the user, we also want to
|
||||
// pass FLAG_BYMOUSE so that we get correct focus ring behavior,
|
||||
// but we don't want to pass FLAG_BYMOUSE if this click event was
|
||||
// caused by the user pressing an accesskey.
|
||||
bool byMouse = (mouseEvent->mInputSource !=
|
||||
MouseEvent_Binding::MOZ_SOURCE_KEYBOARD);
|
||||
bool byTouch = (mouseEvent->mInputSource ==
|
||||
MouseEvent_Binding::MOZ_SOURCE_TOUCH);
|
||||
fm->SetFocus(content,
|
||||
nsIFocusManager::FLAG_BYMOVEFOCUS |
|
||||
(byMouse ? nsIFocusManager::FLAG_BYMOUSE : 0) |
|
||||
(byTouch ? nsIFocusManager::FLAG_BYTOUCH : 0));
|
||||
}
|
||||
}
|
||||
// Dispatch a new click event to |content|
|
||||
// (For compatibility with IE, we do only left click. If
|
||||
// we wanted to interpret the HTML spec very narrowly, we
|
||||
// would do nothing. If we wanted to do something
|
||||
// sensible, we might send more events through like
|
||||
// this.) See bug 7554, bug 49897, and bug 96813.
|
||||
nsEventStatus status = aVisitor.mEventStatus;
|
||||
// Ok to use aVisitor.mEvent as parameter because DispatchClickEvent
|
||||
// will actually create a new event.
|
||||
EventFlags eventFlags;
|
||||
eventFlags.mMultipleActionsPrevented = true;
|
||||
DispatchClickEvent(aVisitor.mPresContext, mouseEvent, content, false,
|
||||
&eventFlags, &status);
|
||||
// Do we care about the status this returned? I don't think we do...
|
||||
// Don't run another <label> off of this click
|
||||
mouseEvent->mFlags.mMultipleActionsPrevented = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -130,90 +177,6 @@ nsresult HTMLLabelElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void HTMLLabelElement::ActivationBehavior(EventChainPostVisitor& aVisitor) {
|
||||
if (!CheckHandleEventPreconditions(aVisitor)) {
|
||||
return;
|
||||
}
|
||||
WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
|
||||
MOZ_ASSERT(mouseEvent && mouseEvent->IsLeftClickEvent());
|
||||
|
||||
nsCOMPtr<Element> target =
|
||||
do_QueryInterface(aVisitor.mEvent->GetOriginalDOMEventTarget());
|
||||
if (nsContentUtils::IsInInteractiveHTMLContent(target, this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Strong ref because event dispatch is going to happen.
|
||||
RefPtr<Element> content = GetLabeledElement();
|
||||
|
||||
if (!content || content->IsDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mHandlingEvent = true;
|
||||
|
||||
LayoutDeviceIntPoint* mouseDownPoint = static_cast<LayoutDeviceIntPoint*>(
|
||||
GetProperty(nsGkAtoms::labelMouseDownPtProperty));
|
||||
|
||||
bool dragSelect = false;
|
||||
if (mouseDownPoint) {
|
||||
LayoutDeviceIntPoint dragDistance = *mouseDownPoint;
|
||||
RemoveProperty(nsGkAtoms::labelMouseDownPtProperty);
|
||||
|
||||
dragDistance -= mouseEvent->mRefPoint;
|
||||
const int CLICK_DISTANCE = 2;
|
||||
dragSelect =
|
||||
dragDistance.x > CLICK_DISTANCE || dragDistance.x < -CLICK_DISTANCE ||
|
||||
dragDistance.y > CLICK_DISTANCE || dragDistance.y < -CLICK_DISTANCE;
|
||||
}
|
||||
// Don't click the for-content if we did drag-select text or if we
|
||||
// have a kbd modifier (which adjusts a selection).
|
||||
if (dragSelect || mouseEvent->IsShift() || mouseEvent->IsControl() ||
|
||||
mouseEvent->IsAlt() || mouseEvent->IsMeta()) {
|
||||
mHandlingEvent = false;
|
||||
return;
|
||||
}
|
||||
// Only set focus on the first click of multiple clicks to prevent
|
||||
// to prevent immediate de-focus.
|
||||
if (mouseEvent->mClickCount <= 1) {
|
||||
if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
|
||||
// Use FLAG_BYMOVEFOCUS here so that the label is scrolled to.
|
||||
// Also, within HTMLInputElement::PostHandleEvent, inputs will
|
||||
// be selected only when focused via a key or when the navigation
|
||||
// flag is used and we want to select the text on label clicks as
|
||||
// well.
|
||||
// If the label has been clicked by the user, we also want to
|
||||
// pass FLAG_BYMOUSE so that we get correct focus ring behavior,
|
||||
// but we don't want to pass FLAG_BYMOUSE if this click event was
|
||||
// caused by the user pressing an accesskey.
|
||||
bool byMouse =
|
||||
(mouseEvent->mInputSource != MouseEvent_Binding::MOZ_SOURCE_KEYBOARD);
|
||||
bool byTouch =
|
||||
(mouseEvent->mInputSource == MouseEvent_Binding::MOZ_SOURCE_TOUCH);
|
||||
fm->SetFocus(content, nsIFocusManager::FLAG_BYMOVEFOCUS |
|
||||
(byMouse ? nsIFocusManager::FLAG_BYMOUSE : 0) |
|
||||
(byTouch ? nsIFocusManager::FLAG_BYTOUCH : 0));
|
||||
}
|
||||
}
|
||||
// Dispatch a new click event to |content|
|
||||
// (For compatibility with IE, we do only left click. If
|
||||
// we wanted to interpret the HTML spec very narrowly, we
|
||||
// would do nothing. If we wanted to do something
|
||||
// sensible, we might send more events through like
|
||||
// this.) See bug 7554, bug 49897, and bug 96813.
|
||||
nsEventStatus status = aVisitor.mEventStatus;
|
||||
// Ok to use aVisitor.mEvent as parameter because DispatchClickEvent
|
||||
// will actually create a new event.
|
||||
EventFlags eventFlags;
|
||||
eventFlags.mMultipleActionsPrevented = true;
|
||||
DispatchClickEvent(aVisitor.mPresContext, mouseEvent, content, false,
|
||||
&eventFlags, &status);
|
||||
// Do we care about the status this returned? I don't think we do...
|
||||
mouseEvent->mFlags.mMultipleActionsPrevented = true;
|
||||
|
||||
mHandlingEvent = false;
|
||||
}
|
||||
|
||||
Result<bool, nsresult> HTMLLabelElement::PerformAccesskey(
|
||||
bool aKeyCausesActivation, bool aIsTrustedEvent) {
|
||||
if (!aKeyCausesActivation) {
|
||||
|
||||
@@ -45,14 +45,10 @@ class HTMLLabelElement final : public nsGenericHTMLElement {
|
||||
const mozilla::dom::CallerType aCallerType,
|
||||
ErrorResult& aError) override;
|
||||
|
||||
// EventTarget
|
||||
void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
|
||||
// nsIContent
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
virtual nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override;
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ActivationBehavior(EventChainPostVisitor& aVisitor) override;
|
||||
|
||||
// Element
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual Result<bool, nsresult> PerformAccesskey(
|
||||
bool aKeyCausesActivation, bool aIsTrustedEvent) override;
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
@@ -69,9 +65,6 @@ class HTMLLabelElement final : public nsGenericHTMLElement {
|
||||
|
||||
// XXX It would be nice if we could use an event flag instead.
|
||||
bool mHandlingEvent;
|
||||
|
||||
private:
|
||||
inline bool CheckHandleEventPreconditions(EventChainVisitor& aVisitor);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Summary)
|
||||
|
||||
@@ -24,60 +23,51 @@ HTMLSummaryElement::~HTMLSummaryElement() = default;
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE(HTMLSummaryElement)
|
||||
|
||||
void HTMLSummaryElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
|
||||
if (WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent()) {
|
||||
aVisitor.mWantsActivationBehavior = mouseEvent->IsLeftClickEvent();
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::GetEventTargetParent(aVisitor);
|
||||
}
|
||||
|
||||
bool HTMLSummaryElement::CheckHandleEventPreconditions(
|
||||
EventChainVisitor& aVisitor) {
|
||||
if (!aVisitor.mPresContext ||
|
||||
aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault ||
|
||||
!IsMainSummary()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<Element> target =
|
||||
do_QueryInterface(aVisitor.mEvent->GetOriginalDOMEventTarget());
|
||||
return !nsContentUtils::IsInInteractiveHTMLContent(target, this);
|
||||
}
|
||||
|
||||
nsresult HTMLSummaryElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
nsresult rv = NS_OK;
|
||||
if (!CheckHandleEventPreconditions(aVisitor)) {
|
||||
if (!aVisitor.mPresContext) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aVisitor.mEvent->HasKeyEventMessage() && aVisitor.mEvent->IsTrusted()) {
|
||||
if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!IsMainSummary()) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
WidgetEvent* const event = aVisitor.mEvent;
|
||||
nsCOMPtr<Element> target =
|
||||
do_QueryInterface(event->GetOriginalDOMEventTarget());
|
||||
if (nsContentUtils::IsInInteractiveHTMLContent(target, this)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (event->HasMouseEventMessage()) {
|
||||
WidgetMouseEvent* mouseEvent = event->AsMouseEvent();
|
||||
|
||||
if (mouseEvent->IsLeftClickEvent()) {
|
||||
RefPtr<HTMLDetailsElement> details = GetDetails();
|
||||
MOZ_ASSERT(details,
|
||||
"Expected to find details since this is the main summary!");
|
||||
|
||||
// When dispatching a synthesized mouse click event to a details element
|
||||
// with 'display: none', both Chrome and Safari do not toggle the 'open'
|
||||
// attribute. We had tried to be compatible with this behavior, but found
|
||||
// more inconsistency in test cases in bug 1245424. So we stop doing that.
|
||||
details->ToggleOpen();
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
return NS_OK;
|
||||
}
|
||||
} // event->HasMouseEventMessage()
|
||||
|
||||
if (event->HasKeyEventMessage() && event->IsTrusted()) {
|
||||
HandleKeyboardActivation(aVisitor);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void HTMLSummaryElement::ActivationBehavior(EventChainPostVisitor& aVisitor) {
|
||||
if (!CheckHandleEventPreconditions(aVisitor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DebugOnly<WidgetMouseEvent*> mouseEvent = aVisitor.mEvent->AsMouseEvent();
|
||||
MOZ_ASSERT(mouseEvent && mouseEvent->IsLeftClickEvent(),
|
||||
"ActivationBehavior should only be called for left click.");
|
||||
|
||||
RefPtr<HTMLDetailsElement> details = GetDetails();
|
||||
MOZ_ASSERT(details,
|
||||
"Expected to find details since this is the main summary!");
|
||||
|
||||
// When dispatching a synthesized mouse click event to a details element
|
||||
// with 'display: none', both Chrome and Safari do not toggle the 'open'
|
||||
// attribute. We had tried to be compatible with this behavior, but found
|
||||
// more inconsistency in test cases in bug 1245424. So we stop doing that.
|
||||
details->ToggleOpen();
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
||||
bool HTMLSummaryElement::IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
|
||||
int32_t* aTabIndex) {
|
||||
bool disallowOverridingFocusability = nsGenericHTMLElement::IsHTMLFocusable(
|
||||
|
||||
@@ -28,9 +28,7 @@ class HTMLSummaryElement final : public nsGenericHTMLElement {
|
||||
|
||||
nsresult Clone(NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
|
||||
nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override;
|
||||
void ActivationBehavior(EventChainPostVisitor& aVisitor) override;
|
||||
|
||||
bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
|
||||
int32_t* aTabIndex) override;
|
||||
@@ -50,9 +48,6 @@ class HTMLSummaryElement final : public nsGenericHTMLElement {
|
||||
|
||||
JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
inline bool CheckHandleEventPreconditions(EventChainVisitor& aVisitor);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
@@ -625,15 +625,6 @@ nsresult nsGenericHTMLElement::PostHandleEventForAnchors(
|
||||
return PostHandleEventForLinks(aVisitor);
|
||||
}
|
||||
|
||||
void nsGenericHTMLElement::ActivationBehaviorForAnchors(
|
||||
EventChainPostVisitor& aVisitor) {
|
||||
if (!CheckHandleEventForAnchorsPreconditions(aVisitor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return ActivationBehaviorForLinks(aVisitor);
|
||||
}
|
||||
|
||||
bool nsGenericHTMLElement::IsHTMLLink(nsIURI** aURI) const {
|
||||
MOZ_ASSERT(aURI, "Must provide aURI out param");
|
||||
|
||||
|
||||
@@ -358,8 +358,6 @@ class nsGenericHTMLElement : public nsGenericHTMLElementBase {
|
||||
void GetEventTargetParentForAnchors(mozilla::EventChainPreVisitor& aVisitor);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
nsresult PostHandleEventForAnchors(mozilla::EventChainPostVisitor& aVisitor);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ActivationBehaviorForAnchors(mozilla::EventChainPostVisitor& aVisitor);
|
||||
bool IsHTMLLink(nsIURI** aURI) const;
|
||||
|
||||
// HTML element methods
|
||||
|
||||
@@ -597,10 +597,6 @@ nsresult MathMLElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
return PostHandleEventForLinks(aVisitor);
|
||||
}
|
||||
|
||||
void MathMLElement::ActivationBehavior(EventChainPostVisitor& aVisitor) {
|
||||
ActivationBehaviorForLinks(aVisitor);
|
||||
}
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE(MathMLElement)
|
||||
|
||||
void MathMLElement::SetIncrementScriptLevel(bool aIncrementScriptLevel,
|
||||
|
||||
@@ -63,8 +63,6 @@ class MathMLElement final : public MathMLElementBase, public Link {
|
||||
void GetEventTargetParent(mozilla::EventChainPreVisitor& aVisitor) override;
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
nsresult PostHandleEvent(mozilla::EventChainPostVisitor& aVisitor) override;
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ActivationBehavior(mozilla::EventChainPostVisitor& aVisitor) override;
|
||||
nsresult Clone(mozilla::dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
// Set during reflow as necessary. Does a style change notification,
|
||||
|
||||
@@ -68,10 +68,6 @@ nsresult SVGAElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
return PostHandleEventForLinks(aVisitor);
|
||||
}
|
||||
|
||||
void SVGAElement::ActivationBehavior(EventChainPostVisitor& aVisitor) {
|
||||
ActivationBehaviorForLinks(aVisitor);
|
||||
}
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGAElement)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#define DOM_SVG_SVGAELEMENT_H_
|
||||
|
||||
#include "Link.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsDOMTokenList.h"
|
||||
#include "SVGAnimatedString.h"
|
||||
#include "mozilla/dom/AnchorAreaFormRelValues.h"
|
||||
@@ -47,8 +46,6 @@ class SVGAElement final : public SVGAElementBase,
|
||||
void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override;
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ActivationBehavior(EventChainPostVisitor& aVisitor) override;
|
||||
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
// nsIContent
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
[Event-dispatch-single-activation-behavior.html]
|
||||
[When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <INPUT type=checkbox></INPUT>, only child should be activated.]
|
||||
expected: FAIL
|
||||
|
||||
[When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <INPUT type=radio></INPUT>, only child should be activated.]
|
||||
expected: FAIL
|
||||
|
||||
[When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.]
|
||||
expected: FAIL
|
||||
|
||||
[When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <FORM><INPUT type=image></INPUT></FORM>, only child should be activated.]
|
||||
expected: FAIL
|
||||
|
||||
[When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.]
|
||||
expected: FAIL
|
||||
|
||||
[When clicking child <INPUT type=checkbox></INPUT> of parent <A></A>, only child should be activated.]
|
||||
expected: FAIL
|
||||
|
||||
[When clicking child <INPUT type=checkbox></INPUT> of parent <AREA></AREA>, only child should be activated.]
|
||||
expected: FAIL
|
||||
|
||||
[When clicking child <INPUT type=radio></INPUT> of parent <A></A>, only child should be activated.]
|
||||
expected: FAIL
|
||||
|
||||
[When clicking child <INPUT type=radio></INPUT> of parent <AREA></AREA>, only child should be activated.]
|
||||
expected: FAIL
|
||||
|
||||
[When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.]
|
||||
expected: FAIL
|
||||
|
||||
[When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.]
|
||||
expected: FAIL
|
||||
|
||||
[When clicking child <LABEL><BUTTON type=button></BUTTON></LABEL> of parent <A></A>, only child should be activated.]
|
||||
expected: FAIL
|
||||
|
||||
[When clicking child <LABEL><BUTTON type=button></BUTTON></LABEL> of parent <AREA></AREA>, only child should be activated.]
|
||||
expected: FAIL
|
||||
Reference in New Issue
Block a user