summaryrefslogtreecommitdiff
path: root/dom/html
diff options
context:
space:
mode:
authorMatt A. Tobin <email@mattatobin.com>2020-04-14 21:24:51 -0400
committerMatt A. Tobin <email@mattatobin.com>2020-04-14 21:25:54 -0400
commitacb801bdca3c4768346f5a9ea2f1272f3f6434fc (patch)
tree07b5c3969b8be3992d9442b58cf925869576e34e /dom/html
parent96b6ea0b94721c6bc1f44f6513f587b1686fec23 (diff)
downloaduxp-acb801bdca3c4768346f5a9ea2f1272f3f6434fc.tar.gz
Bug 1305458 - Changing -moz-appearence on hover breaks change event
* Rename nsIDOMEventTarget::PreHandleEvent to nsIDOMEventTarget::GetEventTargetParent * Add nsIDOMEventTarget::PreHandleEvent * Add EventTargetChainItem::GetFirstEventTarget * Call EventTargetChainItem::PreHandleEvent even it sets mCanHandle=false * Move form control frame focus/blur from nsGenericHTMLFormElement::GetEventTargetParent to PreHandleEvent * Move fire change event from HTMLTextAreaElement::GetEventTargetParent to PreHandleEvent * Refine nsXULElement::GetEventTargetParent * Move dispatch XUL command from nsXULElement::GetEventTargetParent to PreHandleEvent * Move fire events and set value from HTMLInputElement::GetEventTargetParent to PreHandleEvent * Add test case * Let HTMLInputElement delegate event handling to it's parent class * Refine EventTargetChain flags to reduce overheads * Refine event target chain creation * Refine assertion in EventTargetChainItem::Create Tag mcp-graveyard/UXP#1375
Diffstat (limited to 'dom/html')
-rw-r--r--dom/html/HTMLAnchorElement.cpp4
-rw-r--r--dom/html/HTMLAnchorElement.h3
-rw-r--r--dom/html/HTMLAreaElement.cpp4
-rw-r--r--dom/html/HTMLAreaElement.h3
-rw-r--r--dom/html/HTMLButtonElement.cpp4
-rw-r--r--dom/html/HTMLButtonElement.h3
-rw-r--r--dom/html/HTMLCanvasElement.cpp4
-rw-r--r--dom/html/HTMLCanvasElement.h3
-rw-r--r--dom/html/HTMLFieldSetElement.cpp4
-rw-r--r--dom/html/HTMLFieldSetElement.h3
-rw-r--r--dom/html/HTMLFormElement.cpp4
-rw-r--r--dom/html/HTMLFormElement.h3
-rw-r--r--dom/html/HTMLImageElement.cpp4
-rw-r--r--dom/html/HTMLImageElement.h3
-rw-r--r--dom/html/HTMLInputElement.cpp90
-rw-r--r--dom/html/HTMLInputElement.h4
-rw-r--r--dom/html/HTMLLinkElement.cpp4
-rw-r--r--dom/html/HTMLLinkElement.h3
-rw-r--r--dom/html/HTMLMenuItemElement.cpp4
-rw-r--r--dom/html/HTMLMenuItemElement.h3
-rw-r--r--dom/html/HTMLOptGroupElement.cpp4
-rw-r--r--dom/html/HTMLOptGroupElement.h3
-rw-r--r--dom/html/HTMLSelectElement.cpp4
-rw-r--r--dom/html/HTMLSelectElement.h3
-rw-r--r--dom/html/HTMLTextAreaElement.cpp17
-rw-r--r--dom/html/HTMLTextAreaElement.h4
-rw-r--r--dom/html/nsGenericHTMLElement.cpp21
-rw-r--r--dom/html/nsGenericHTMLElement.h9
28 files changed, 147 insertions, 75 deletions
diff --git a/dom/html/HTMLAnchorElement.cpp b/dom/html/HTMLAnchorElement.cpp
index a6cfacc53d..501d6e3d06 100644
--- a/dom/html/HTMLAnchorElement.cpp
+++ b/dom/html/HTMLAnchorElement.cpp
@@ -252,9 +252,9 @@ HTMLAnchorElement::IsHTMLFocusable(bool aWithMouse,
}
nsresult
-HTMLAnchorElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
+HTMLAnchorElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
- return PreHandleEventForAnchors(aVisitor);
+ return GetEventTargetParentForAnchors(aVisitor);
}
nsresult
diff --git a/dom/html/HTMLAnchorElement.h b/dom/html/HTMLAnchorElement.h
index 2cb04ad939..027d8d689a 100644
--- a/dom/html/HTMLAnchorElement.h
+++ b/dom/html/HTMLAnchorElement.h
@@ -58,7 +58,8 @@ public:
bool aNullParent = true) override;
virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) override;
- virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
+ virtual nsresult GetEventTargetParent(
+ EventChainPreVisitor& aVisitor) override;
virtual nsresult PostHandleEvent(
EventChainPostVisitor& aVisitor) override;
virtual bool IsLink(nsIURI** aURI) const override;
diff --git a/dom/html/HTMLAreaElement.cpp b/dom/html/HTMLAreaElement.cpp
index 098081b8b0..213d4831dd 100644
--- a/dom/html/HTMLAreaElement.cpp
+++ b/dom/html/HTMLAreaElement.cpp
@@ -81,9 +81,9 @@ HTMLAreaElement::SetTarget(const nsAString& aValue)
}
nsresult
-HTMLAreaElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
+HTMLAreaElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
- return PreHandleEventForAnchors(aVisitor);
+ return GetEventTargetParentForAnchors(aVisitor);
}
nsresult
diff --git a/dom/html/HTMLAreaElement.h b/dom/html/HTMLAreaElement.h
index 650c0fd8fd..c2ed7a9283 100644
--- a/dom/html/HTMLAreaElement.h
+++ b/dom/html/HTMLAreaElement.h
@@ -44,7 +44,8 @@ public:
// nsIDOMHTMLAreaElement
NS_DECL_NSIDOMHTMLAREAELEMENT
- virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
+ virtual nsresult GetEventTargetParent(
+ EventChainPreVisitor& aVisitor) override;
virtual nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override;
virtual bool IsLink(nsIURI** aURI) const override;
virtual void GetLinkTarget(nsAString& aTarget) override;
diff --git a/dom/html/HTMLButtonElement.cpp b/dom/html/HTMLButtonElement.cpp
index 435aa9f7fd..aad1c412bc 100644
--- a/dom/html/HTMLButtonElement.cpp
+++ b/dom/html/HTMLButtonElement.cpp
@@ -207,7 +207,7 @@ HTMLButtonElement::IsDisabledForEvents(EventMessage aMessage)
}
nsresult
-HTMLButtonElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
+HTMLButtonElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = false;
if (IsDisabledForEvents(aVisitor.mEvent->mMessage)) {
@@ -235,7 +235,7 @@ HTMLButtonElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
}
}
- return nsGenericHTMLElement::PreHandleEvent(aVisitor);
+ return nsGenericHTMLElement::GetEventTargetParent(aVisitor);
}
nsresult
diff --git a/dom/html/HTMLButtonElement.h b/dom/html/HTMLButtonElement.h
index ecd9e03d73..a8d206dd69 100644
--- a/dom/html/HTMLButtonElement.h
+++ b/dom/html/HTMLButtonElement.h
@@ -57,7 +57,8 @@ public:
virtual void FieldSetDisabledChanged(bool aNotify) override;
// nsIDOMEventTarget
- virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
+ virtual nsresult GetEventTargetParent(
+ EventChainPreVisitor& aVisitor) override;
virtual nsresult PostHandleEvent(
EventChainPostVisitor& aVisitor) override;
diff --git a/dom/html/HTMLCanvasElement.cpp b/dom/html/HTMLCanvasElement.cpp
index 4b5deab187..803c60e8ac 100644
--- a/dom/html/HTMLCanvasElement.cpp
+++ b/dom/html/HTMLCanvasElement.cpp
@@ -574,7 +574,7 @@ HTMLCanvasElement::CopyInnerTo(Element* aDest)
return rv;
}
-nsresult HTMLCanvasElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
+nsresult HTMLCanvasElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
if (aVisitor.mEvent->mClass == eMouseEventClass) {
WidgetMouseEventBase* evt = (WidgetMouseEventBase*)aVisitor.mEvent;
@@ -592,7 +592,7 @@ nsresult HTMLCanvasElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
aVisitor.mCanHandle = true;
}
}
- return nsGenericHTMLElement::PreHandleEvent(aVisitor);
+ return nsGenericHTMLElement::GetEventTargetParent(aVisitor);
}
nsChangeHint
diff --git a/dom/html/HTMLCanvasElement.h b/dom/html/HTMLCanvasElement.h
index e77db6ff1a..de26c475a3 100644
--- a/dom/html/HTMLCanvasElement.h
+++ b/dom/html/HTMLCanvasElement.h
@@ -312,7 +312,8 @@ public:
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
nsresult CopyInnerTo(mozilla::dom::Element* aDest);
- virtual nsresult PreHandleEvent(mozilla::EventChainPreVisitor& aVisitor) override;
+ virtual nsresult GetEventTargetParent(
+ mozilla::EventChainPreVisitor& aVisitor) override;
/*
* Helpers called by various users of Canvas
diff --git a/dom/html/HTMLFieldSetElement.cpp b/dom/html/HTMLFieldSetElement.cpp
index d72fd1061a..c008b9b6d6 100644
--- a/dom/html/HTMLFieldSetElement.cpp
+++ b/dom/html/HTMLFieldSetElement.cpp
@@ -70,7 +70,7 @@ HTMLFieldSetElement::IsDisabledForEvents(EventMessage aMessage)
// nsIContent
nsresult
-HTMLFieldSetElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
+HTMLFieldSetElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
// Do not process any DOM events if the element is disabled.
aVisitor.mCanHandle = false;
@@ -78,7 +78,7 @@ HTMLFieldSetElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
return NS_OK;
}
- return nsGenericHTMLFormElement::PreHandleEvent(aVisitor);
+ return nsGenericHTMLFormElement::GetEventTargetParent(aVisitor);
}
nsresult
diff --git a/dom/html/HTMLFieldSetElement.h b/dom/html/HTMLFieldSetElement.h
index 96fff4582b..1e9f0214f5 100644
--- a/dom/html/HTMLFieldSetElement.h
+++ b/dom/html/HTMLFieldSetElement.h
@@ -40,7 +40,8 @@ public:
NS_DECL_NSIDOMHTMLFIELDSETELEMENT
// nsIContent
- virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
+ virtual nsresult GetEventTargetParent(
+ EventChainPreVisitor& aVisitor) override;
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
const nsAttrValue* aValue, bool aNotify) override;
diff --git a/dom/html/HTMLFormElement.cpp b/dom/html/HTMLFormElement.cpp
index 6bea19a2bf..bdc05b053c 100644
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -489,7 +489,7 @@ HTMLFormElement::UnbindFromTree(bool aDeep, bool aNullParent)
}
nsresult
-HTMLFormElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
+HTMLFormElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
aVisitor.mWantsWillHandleEvent = true;
if (aVisitor.mEvent->mOriginalTarget == static_cast<nsIContent*>(this)) {
@@ -513,7 +513,7 @@ HTMLFormElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
mGeneratingReset = true;
}
}
- return nsGenericHTMLElement::PreHandleEvent(aVisitor);
+ return nsGenericHTMLElement::GetEventTargetParent(aVisitor);
}
nsresult
diff --git a/dom/html/HTMLFormElement.h b/dom/html/HTMLFormElement.h
index b3e836f5f2..e45d4c10d7 100644
--- a/dom/html/HTMLFormElement.h
+++ b/dom/html/HTMLFormElement.h
@@ -93,7 +93,8 @@ public:
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult) override;
- virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
+ virtual nsresult GetEventTargetParent(
+ EventChainPreVisitor& aVisitor) override;
virtual nsresult WillHandleEvent(
EventChainPostVisitor& aVisitor) override;
virtual nsresult PostHandleEvent(
diff --git a/dom/html/HTMLImageElement.cpp b/dom/html/HTMLImageElement.cpp
index fab1cdef4b..49cbebc5a4 100644
--- a/dom/html/HTMLImageElement.cpp
+++ b/dom/html/HTMLImageElement.cpp
@@ -437,7 +437,7 @@ HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
}
nsresult
-HTMLImageElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
+HTMLImageElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
// We handle image element with attribute ismap in its corresponding frame
// element. Set mMultipleActionsPrevented here to prevent the click event
@@ -446,7 +446,7 @@ HTMLImageElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
if (mouseEvent && mouseEvent->IsLeftClickEvent() && IsMap()) {
mouseEvent->mFlags.mMultipleActionsPrevented = true;
}
- return nsGenericHTMLElement::PreHandleEvent(aVisitor);
+ return nsGenericHTMLElement::GetEventTargetParent(aVisitor);
}
bool
diff --git a/dom/html/HTMLImageElement.h b/dom/html/HTMLImageElement.h
index 62323e8016..41730c2e5b 100644
--- a/dom/html/HTMLImageElement.h
+++ b/dom/html/HTMLImageElement.h
@@ -70,7 +70,8 @@ public:
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const override;
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
- virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
+ virtual nsresult GetEventTargetParent(
+ EventChainPreVisitor& aVisitor) override;
bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) override;
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
index 0b879bb9b4..d5fca28f6b 100644
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -147,6 +147,8 @@ namespace dom {
#define NS_CONTROL_TYPE(bits) ((bits) & ~( \
NS_OUTER_ACTIVATE_EVENT | NS_ORIGINAL_CHECKED_VALUE | NS_NO_CONTENT_DISPATCH | \
NS_ORIGINAL_INDETERMINATE_VALUE))
+#define NS_PRE_HANDLE_BLUR_EVENT (1 << 13)
+#define NS_PRE_HANDLE_INPUT_EVENT (1 << 14)
// whether textfields should be selected once focused:
// -1: no, 1: yes, 0: uninitialized
@@ -3738,7 +3740,7 @@ HTMLInputElement::IsDisabledForEvents(EventMessage aMessage)
}
nsresult
-HTMLInputElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
+HTMLInputElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
// Do not process any DOM events if the element is disabled
aVisitor.mCanHandle = false;
@@ -3755,7 +3757,7 @@ HTMLInputElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
//FIXME Allow submission etc. also when there is no prescontext, Bug 329509.
if (!aVisitor.mPresContext) {
- return nsGenericHTMLElement::PreHandleEvent(aVisitor);
+ return nsGenericHTMLFormElementWithState::GetEventTargetParent(aVisitor);
}
//
// Web pages expect the value of a radio button or checkbox to be set
@@ -3865,23 +3867,16 @@ HTMLInputElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
// Fire onchange (if necessary), before we do the blur, bug 357684.
if (aVisitor.mEvent->mMessage == eBlur) {
- // Experimental mobile types rely on the system UI to prevent users to not
- // set invalid values but we have to be extra-careful. Especially if the
- // option has been enabled on desktop.
- if (IsExperimentalMobileType(mType)) {
- nsAutoString aValue;
- GetValueInternal(aValue);
- nsresult rv =
- SetValueInternal(aValue, nsTextEditorState::eSetValue_Internal);
- NS_ENSURE_SUCCESS(rv, rv);
- }
- FireChangeEventIfNeeded();
+ // We set NS_PRE_HANDLE_BLUR_EVENT here and handle it in PreHandleEvent to
+ // prevent breaking event target chain creation.
+ aVisitor.mWantsPreHandleEvent = true;
+ aVisitor.mItemFlags |= NS_PRE_HANDLE_BLUR_EVENT;
}
if (mType == NS_FORM_INPUT_RANGE &&
(aVisitor.mEvent->mMessage == eFocus ||
aVisitor.mEvent->mMessage == eBlur)) {
- // Just as nsGenericHTMLFormElementWithState::PreHandleEvent calls
+ // Just as nsGenericHTMLFormElementWithState::GetEventTargetParent calls
// nsIFormControlFrame::SetFocus, we handle focus here.
nsIFrame* frame = GetPrimaryFrame();
if (frame) {
@@ -3969,10 +3964,11 @@ HTMLInputElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
}
}
- nsresult rv = nsGenericHTMLFormElementWithState::PreHandleEvent(aVisitor);
+ nsresult rv = nsGenericHTMLFormElementWithState::GetEventTargetParent(aVisitor);
- // We do this after calling the base class' PreHandleEvent so that
- // nsIContent::PreHandleEvent doesn't reset any change we make to mCanHandle.
+ // We do this after calling the base class' GetEventTargetParent so that
+ // nsIContent::GetEventTargetParent doesn't reset any change we make to
+ // mCanHandle.
if (mType == NS_FORM_INPUT_NUMBER &&
aVisitor.mEvent->IsTrusted() &&
aVisitor.mEvent->mOriginalTarget != this) {
@@ -3987,18 +3983,10 @@ HTMLInputElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
}
if (textControl && aVisitor.mEvent->mOriginalTarget == textControl) {
if (aVisitor.mEvent->mMessage == eEditorInput) {
- // Propogate the anon text control's new value to our HTMLInputElement:
- nsAutoString value;
- numberControlFrame->GetValueOfAnonTextControl(value);
- numberControlFrame->HandlingInputEvent(true);
- nsWeakFrame weakNumberControlFrame(numberControlFrame);
- rv = SetValueInternal(value,
- nsTextEditorState::eSetValue_BySetUserInput |
- nsTextEditorState::eSetValue_Notify);
- NS_ENSURE_SUCCESS(rv, rv);
- if (weakNumberControlFrame.IsAlive()) {
- numberControlFrame->HandlingInputEvent(false);
- }
+ aVisitor.mWantsPreHandleEvent = true;
+ // We set NS_PRE_HANDLE_INPUT_EVENT here and handle it in PreHandleEvent
+ // to prevent breaking event target chain creation.
+ aVisitor.mItemFlags |= NS_PRE_HANDLE_INPUT_EVENT;
}
else if (aVisitor.mEvent->mMessage == eFormChange) {
// We cancel the DOM 'change' event that is fired for any change to our
@@ -4037,6 +4025,50 @@ HTMLInputElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
return rv;
}
+nsresult
+HTMLInputElement::PreHandleEvent(EventChainVisitor& aVisitor)
+{
+ if (!aVisitor.mPresContext) {
+ return nsGenericHTMLFormElementWithState::PreHandleEvent(aVisitor);
+ }
+ nsresult rv;
+ if (aVisitor.mItemFlags & NS_PRE_HANDLE_BLUR_EVENT) {
+ MOZ_ASSERT(aVisitor.mEvent->mMessage == eBlur);
+ // Experimental mobile types rely on the system UI to prevent users to not
+ // set invalid values but we have to be extra-careful. Especially if the
+ // option has been enabled on desktop.
+ if (IsExperimentalMobileType(mType)) {
+ nsAutoString aValue;
+ GetValueInternal(aValue);
+ nsresult rv =
+ SetValueInternal(aValue, nsTextEditorState::eSetValue_Internal);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ FireChangeEventIfNeeded();
+ }
+ rv = nsGenericHTMLFormElementWithState::PreHandleEvent(aVisitor);
+ if (aVisitor.mItemFlags & NS_PRE_HANDLE_INPUT_EVENT) {
+ nsNumberControlFrame* numberControlFrame = do_QueryFrame(GetPrimaryFrame());
+ MOZ_ASSERT(aVisitor.mEvent->mMessage == eEditorInput);
+ MOZ_ASSERT(numberControlFrame);
+ MOZ_ASSERT(numberControlFrame->GetAnonTextControl() ==
+ aVisitor.mEvent->mOriginalTarget);
+ // Propogate the anon text control's new value to our HTMLInputElement:
+ nsAutoString value;
+ numberControlFrame->GetValueOfAnonTextControl(value);
+ numberControlFrame->HandlingInputEvent(true);
+ nsWeakFrame weakNumberControlFrame(numberControlFrame);
+ rv = SetValueInternal(value,
+ nsTextEditorState::eSetValue_BySetUserInput |
+ nsTextEditorState::eSetValue_Notify);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (weakNumberControlFrame.IsAlive()) {
+ numberControlFrame->HandlingInputEvent(false);
+ }
+ }
+ return rv;
+}
+
void
HTMLInputElement::StartRangeThumbDrag(WidgetGUIEvent* aEvent)
{
diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h
index 98a5904437..98c74893e6 100644
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -185,7 +185,9 @@ public:
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const override;
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
- virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
+ virtual nsresult GetEventTargetParent(
+ EventChainPreVisitor& aVisitor) override;
+ virtual nsresult PreHandleEvent(EventChainVisitor& aVisitor) override;
virtual nsresult PostHandleEvent(
EventChainPostVisitor& aVisitor) override;
void PostHandleEventForRangeThumb(EventChainPostVisitor& aVisitor);
diff --git a/dom/html/HTMLLinkElement.cpp b/dom/html/HTMLLinkElement.cpp
index 8afe767bdb..0a2cdaaf40 100644
--- a/dom/html/HTMLLinkElement.cpp
+++ b/dom/html/HTMLLinkElement.cpp
@@ -421,9 +421,9 @@ HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
}
nsresult
-HTMLLinkElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
+HTMLLinkElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
- return PreHandleEventForAnchors(aVisitor);
+ return GetEventTargetParentForAnchors(aVisitor);
}
nsresult
diff --git a/dom/html/HTMLLinkElement.h b/dom/html/HTMLLinkElement.h
index 421b149e96..1fa154f41e 100644
--- a/dom/html/HTMLLinkElement.h
+++ b/dom/html/HTMLLinkElement.h
@@ -46,7 +46,8 @@ public:
void UpdateImport();
// nsIDOMEventTarget
- virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
+ virtual nsresult GetEventTargetParent(
+ EventChainPreVisitor& aVisitor) override;
virtual nsresult PostHandleEvent(
EventChainPostVisitor& aVisitor) override;
diff --git a/dom/html/HTMLMenuItemElement.cpp b/dom/html/HTMLMenuItemElement.cpp
index ca8bb4feb5..6a8ad8174c 100644
--- a/dom/html/HTMLMenuItemElement.cpp
+++ b/dom/html/HTMLMenuItemElement.cpp
@@ -252,7 +252,7 @@ HTMLMenuItemElement::SetChecked(bool aChecked)
}
nsresult
-HTMLMenuItemElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
+HTMLMenuItemElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
if (aVisitor.mEvent->mMessage == eMouseClick) {
@@ -283,7 +283,7 @@ HTMLMenuItemElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
aVisitor.mItemFlags |= mType;
}
- return nsGenericHTMLElement::PreHandleEvent(aVisitor);
+ return nsGenericHTMLElement::GetEventTargetParent(aVisitor);
}
nsresult
diff --git a/dom/html/HTMLMenuItemElement.h b/dom/html/HTMLMenuItemElement.h
index 3c19b1170e..1da63edd05 100644
--- a/dom/html/HTMLMenuItemElement.h
+++ b/dom/html/HTMLMenuItemElement.h
@@ -36,7 +36,8 @@ public:
// nsIDOMHTMLMenuItemElement
NS_DECL_NSIDOMHTMLMENUITEMELEMENT
- virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
+ virtual nsresult GetEventTargetParent(
+ EventChainPreVisitor& aVisitor) override;
virtual nsresult PostHandleEvent(
EventChainPostVisitor& aVisitor) override;
diff --git a/dom/html/HTMLOptGroupElement.cpp b/dom/html/HTMLOptGroupElement.cpp
index 9e738961d8..0424ccef32 100644
--- a/dom/html/HTMLOptGroupElement.cpp
+++ b/dom/html/HTMLOptGroupElement.cpp
@@ -48,7 +48,7 @@ NS_IMPL_STRING_ATTR(HTMLOptGroupElement, Label, label)
nsresult
-HTMLOptGroupElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
+HTMLOptGroupElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = false;
// Do not process any DOM events if the element is disabled
@@ -65,7 +65,7 @@ HTMLOptGroupElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
}
}
- return nsGenericHTMLElement::PreHandleEvent(aVisitor);
+ return nsGenericHTMLElement::GetEventTargetParent(aVisitor);
}
Element*
diff --git a/dom/html/HTMLOptGroupElement.h b/dom/html/HTMLOptGroupElement.h
index e46a6a953f..c669f43b48 100644
--- a/dom/html/HTMLOptGroupElement.h
+++ b/dom/html/HTMLOptGroupElement.h
@@ -35,7 +35,8 @@ public:
virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) override;
// nsIContent
- virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
+ virtual nsresult GetEventTargetParent(
+ EventChainPreVisitor& aVisitor) override;
virtual EventStates IntrinsicState() const override;
diff --git a/dom/html/HTMLSelectElement.cpp b/dom/html/HTMLSelectElement.cpp
index 9ba0a1efe9..272a165781 100644
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -1442,14 +1442,14 @@ HTMLSelectElement::IsDisabledForEvents(EventMessage aMessage)
}
nsresult
-HTMLSelectElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
+HTMLSelectElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = false;
if (IsDisabledForEvents(aVisitor.mEvent->mMessage)) {
return NS_OK;
}
- return nsGenericHTMLFormElementWithState::PreHandleEvent(aVisitor);
+ return nsGenericHTMLFormElementWithState::GetEventTargetParent(aVisitor);
}
nsresult
diff --git a/dom/html/HTMLSelectElement.h b/dom/html/HTMLSelectElement.h
index dc1075cd7d..4cb5f90c9f 100644
--- a/dom/html/HTMLSelectElement.h
+++ b/dom/html/HTMLSelectElement.h
@@ -278,7 +278,8 @@ public:
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
// nsIContent
- virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
+ virtual nsresult GetEventTargetParent(
+ EventChainPreVisitor& aVisitor) override;
virtual nsresult PostHandleEvent(
EventChainPostVisitor& aVisitor) override;
diff --git a/dom/html/HTMLTextAreaElement.cpp b/dom/html/HTMLTextAreaElement.cpp
index 42bc02435e..796d8a49e9 100644
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -506,7 +506,7 @@ HTMLTextAreaElement::IsDisabledForEvents(EventMessage aMessage)
}
nsresult
-HTMLTextAreaElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
+HTMLTextAreaElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = false;
if (IsDisabledForEvents(aVisitor.mEvent->mMessage)) {
@@ -534,11 +534,22 @@ HTMLTextAreaElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
aVisitor.mEvent->mFlags.mNoContentDispatch = false;
}
- // Fire onchange (if necessary), before we do the blur, bug 370521.
if (aVisitor.mEvent->mMessage == eBlur) {
- FireChangeEventIfNeeded();
+ // Set mWantsPreHandleEvent and fire change event in PreHandleEvent to
+ // prevent it breaks event target chain creation.
+ aVisitor.mWantsPreHandleEvent = true;
}
+ return nsGenericHTMLFormElementWithState::GetEventTargetParent(aVisitor);
+}
+
+nsresult
+HTMLTextAreaElement::PreHandleEvent(EventChainVisitor& aVisitor)
+{
+ if (aVisitor.mEvent->mMessage == eBlur) {
+ // Fire onchange (if necessary), before we do the blur, bug 370521.
+ FireChangeEventIfNeeded();
+ }
return nsGenericHTMLFormElementWithState::PreHandleEvent(aVisitor);
}
diff --git a/dom/html/HTMLTextAreaElement.h b/dom/html/HTMLTextAreaElement.h
index 0390828182..bfc7d203d8 100644
--- a/dom/html/HTMLTextAreaElement.h
+++ b/dom/html/HTMLTextAreaElement.h
@@ -125,7 +125,9 @@ public:
int32_t aModType) const override;
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const override;
- virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
+ virtual nsresult GetEventTargetParent(
+ EventChainPreVisitor& aVisitor) override;
+ virtual nsresult PreHandleEvent(EventChainVisitor& aVisitor) override;
virtual nsresult PostHandleEvent(
EventChainPostVisitor& aVisitor) override;
diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp
index 78e4d5b958..394a77a590 100644
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -607,16 +607,16 @@ nsGenericHTMLElement::CheckHandleEventForAnchorsPreconditions(
}
nsresult
-nsGenericHTMLElement::PreHandleEventForAnchors(EventChainPreVisitor& aVisitor)
+nsGenericHTMLElement::GetEventTargetParentForAnchors(EventChainPreVisitor& aVisitor)
{
- nsresult rv = nsGenericHTMLElementBase::PreHandleEvent(aVisitor);
+ nsresult rv = nsGenericHTMLElementBase::GetEventTargetParent(aVisitor);
NS_ENSURE_SUCCESS(rv, rv);
if (!CheckHandleEventForAnchorsPreconditions(aVisitor)) {
return NS_OK;
}
- return PreHandleEventForLinks(aVisitor);
+ return GetEventTargetParentForLinks(aVisitor);
}
nsresult
@@ -2081,7 +2081,19 @@ nsGenericHTMLFormElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
}
nsresult
-nsGenericHTMLFormElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
+nsGenericHTMLFormElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
+{
+ if (aVisitor.mEvent->IsTrusted() && (aVisitor.mEvent->mMessage == eFocus ||
+ aVisitor.mEvent->mMessage == eBlur)) {
+ // We have to handle focus/blur event to change focus states in
+ // PreHandleEvent to prevent it breaks event target chain creation.
+ aVisitor.mWantsPreHandleEvent = true;
+ }
+ return nsGenericHTMLElement::GetEventTargetParent(aVisitor);
+}
+
+nsresult
+nsGenericHTMLFormElement::PreHandleEvent(EventChainVisitor& aVisitor)
{
if (aVisitor.mEvent->IsTrusted()) {
switch (aVisitor.mEvent->mMessage) {
@@ -2105,7 +2117,6 @@ nsGenericHTMLFormElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
break;
}
}
-
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
}
diff --git a/dom/html/nsGenericHTMLElement.h b/dom/html/nsGenericHTMLElement.h
index 2b8b608b9d..ab4391aa1e 100644
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -498,7 +498,8 @@ public:
*/
bool CheckHandleEventForAnchorsPreconditions(
mozilla::EventChainVisitor& aVisitor);
- nsresult PreHandleEventForAnchors(mozilla::EventChainPreVisitor& aVisitor);
+ nsresult GetEventTargetParentForAnchors(
+ mozilla::EventChainPreVisitor& aVisitor);
nsresult PostHandleEventForAnchors(mozilla::EventChainPostVisitor& aVisitor);
bool IsHTMLLink(nsIURI** aURI) const;
@@ -1219,8 +1220,10 @@ public:
virtual IMEState GetDesiredIMEState() override;
virtual mozilla::EventStates IntrinsicState() const override;
- virtual nsresult PreHandleEvent(
+ virtual nsresult GetEventTargetParent(
mozilla::EventChainPreVisitor& aVisitor) override;
+ virtual nsresult PreHandleEvent(
+ mozilla::EventChainVisitor& aVisitor) override;
/**
* This callback is called by a fieldest on all its elements whenever its
@@ -1305,7 +1308,7 @@ protected:
static bool FormIdUpdated(Element* aOldElement, Element* aNewElement,
void* aData);
- // Returns true if the event should not be handled from PreHandleEvent
+ // Returns true if the event should not be handled from GetEventTargetParent
bool IsElementDisabledForEvents(mozilla::EventMessage aMessage,
nsIFrame* aFrame);