From 5352b69a9286223272c0ed072900b4c78ba2ed7c Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Tue, 14 Apr 2020 21:24:51 -0400 Subject: 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 #1375 --- dom/archivereader/ArchiveRequest.cpp | 2 +- dom/archivereader/ArchiveRequest.h | 3 +- dom/base/Attr.cpp | 2 +- dom/base/Attr.h | 2 +- dom/base/Element.cpp | 7 +- dom/base/Element.h | 2 +- dom/base/FragmentOrElement.cpp | 2 +- dom/base/nsDocument.cpp | 2 +- dom/base/nsDocument.h | 2 +- dom/base/nsGenConImageContent.cpp | 4 +- dom/base/nsGlobalWindow.cpp | 7 +- dom/base/nsIContent.h | 2 +- dom/base/nsINode.cpp | 2 +- dom/base/nsInProcessTabChildGlobal.cpp | 4 +- dom/base/nsInProcessTabChildGlobal.h | 4 +- dom/base/nsWindowRoot.cpp | 2 +- dom/events/DOMEventTargetHelper.cpp | 2 +- dom/events/DOMEventTargetHelper.h | 4 +- dom/events/EventDispatcher.cpp | 256 ++++++++++++++++++++-------- dom/events/EventDispatcher.h | 24 ++- dom/events/test/mochitest.ini | 1 + dom/events/test/test_bug1305458.html | 50 ++++++ dom/html/HTMLAnchorElement.cpp | 4 +- dom/html/HTMLAnchorElement.h | 3 +- dom/html/HTMLAreaElement.cpp | 4 +- dom/html/HTMLAreaElement.h | 3 +- dom/html/HTMLButtonElement.cpp | 4 +- dom/html/HTMLButtonElement.h | 3 +- dom/html/HTMLCanvasElement.cpp | 4 +- dom/html/HTMLCanvasElement.h | 3 +- dom/html/HTMLFieldSetElement.cpp | 4 +- dom/html/HTMLFieldSetElement.h | 3 +- dom/html/HTMLFormElement.cpp | 4 +- dom/html/HTMLFormElement.h | 3 +- dom/html/HTMLImageElement.cpp | 4 +- dom/html/HTMLImageElement.h | 3 +- dom/html/HTMLInputElement.cpp | 90 ++++++---- dom/html/HTMLInputElement.h | 4 +- dom/html/HTMLLinkElement.cpp | 4 +- dom/html/HTMLLinkElement.h | 3 +- dom/html/HTMLMenuItemElement.cpp | 4 +- dom/html/HTMLMenuItemElement.h | 3 +- dom/html/HTMLOptGroupElement.cpp | 4 +- dom/html/HTMLOptGroupElement.h | 3 +- dom/html/HTMLSelectElement.cpp | 4 +- dom/html/HTMLSelectElement.h | 3 +- dom/html/HTMLTextAreaElement.cpp | 17 +- dom/html/HTMLTextAreaElement.h | 4 +- dom/html/nsGenericHTMLElement.cpp | 21 ++- dom/html/nsGenericHTMLElement.h | 9 +- dom/indexedDB/IDBFileHandle.cpp | 2 +- dom/indexedDB/IDBFileHandle.h | 2 +- dom/indexedDB/IDBFileRequest.cpp | 2 +- dom/indexedDB/IDBFileRequest.h | 2 +- dom/indexedDB/IDBRequest.cpp | 2 +- dom/indexedDB/IDBRequest.h | 2 +- dom/indexedDB/IDBTransaction.cpp | 2 +- dom/indexedDB/IDBTransaction.h | 2 +- dom/interfaces/events/nsIDOMEventTarget.idl | 15 +- dom/ipc/TabChild.h | 2 +- dom/mathml/nsMathMLElement.cpp | 6 +- dom/mathml/nsMathMLElement.h | 2 +- dom/svg/SVGAElement.cpp | 6 +- dom/svg/SVGAElement.h | 3 +- dom/svg/SVGSVGElement.cpp | 4 +- dom/svg/SVGSVGElement.h | 3 +- dom/workers/SharedWorker.cpp | 4 +- dom/workers/SharedWorker.h | 2 +- dom/xul/nsXULElement.cpp | 124 ++++++++------ dom/xul/nsXULElement.h | 10 +- 70 files changed, 547 insertions(+), 258 deletions(-) create mode 100644 dom/events/test/test_bug1305458.html diff --git a/dom/archivereader/ArchiveRequest.cpp b/dom/archivereader/ArchiveRequest.cpp index ec1686804..c4b19f56b 100644 --- a/dom/archivereader/ArchiveRequest.cpp +++ b/dom/archivereader/ArchiveRequest.cpp @@ -69,7 +69,7 @@ ArchiveRequest::~ArchiveRequest() } nsresult -ArchiveRequest::PreHandleEvent(EventChainPreVisitor& aVisitor) +ArchiveRequest::GetEventTargetParent(EventChainPreVisitor& aVisitor) { aVisitor.mCanHandle = true; aVisitor.mParentTarget = nullptr; diff --git a/dom/archivereader/ArchiveRequest.h b/dom/archivereader/ArchiveRequest.h index 3988f1aa1..3081a3e42 100644 --- a/dom/archivereader/ArchiveRequest.h +++ b/dom/archivereader/ArchiveRequest.h @@ -38,7 +38,8 @@ public: ArchiveReader* aReader); // nsIDOMEventTarget - virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override; + virtual nsresult GetEventTargetParent( + EventChainPreVisitor& aVisitor) override; public: // This is called by the DOMArchiveRequestEvent diff --git a/dom/base/Attr.cpp b/dom/base/Attr.cpp index 71b559392..df05ef5cb 100644 --- a/dom/base/Attr.cpp +++ b/dom/base/Attr.cpp @@ -344,7 +344,7 @@ Attr::RemoveChildAt(uint32_t aIndex, bool aNotify) } nsresult -Attr::PreHandleEvent(EventChainPreVisitor& aVisitor) +Attr::GetEventTargetParent(EventChainPreVisitor& aVisitor) { aVisitor.mCanHandle = true; return NS_OK; diff --git a/dom/base/Attr.h b/dom/base/Attr.h index 3f80030d2..39ac8b195 100644 --- a/dom/base/Attr.h +++ b/dom/base/Attr.h @@ -54,7 +54,7 @@ public: // nsIDOMAttr interface NS_DECL_NSIDOMATTR - virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override; + virtual nsresult GetEventTargetParent(EventChainPreVisitor& aVisitor) override; // nsIAttribute interface void SetMap(nsDOMAttributeMap *aMap) override; diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index c8467e036..5a92853ae 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -3129,7 +3129,7 @@ Element::CheckHandleEventForLinksPrecondition(EventChainVisitor& aVisitor, } nsresult -Element::PreHandleEventForLinks(EventChainPreVisitor& aVisitor) +Element::GetEventTargetParentForLinks(EventChainPreVisitor& aVisitor) { // Optimisation: return early if this event doesn't interest us. // IMPORTANT: this switch and the switch below it must be kept in sync! @@ -3151,8 +3151,9 @@ Element::PreHandleEventForLinks(EventChainPreVisitor& aVisitor) nsresult rv = NS_OK; - // We do the status bar updates in PreHandleEvent so that the status bar gets - // updated even if the event is consumed before we have a chance to set it. + // We do the status bar updates in GetEventTargetParent so that the status bar + // gets updated even if the event is consumed before we have a chance to set + // it. switch (aVisitor.mEvent->mMessage) { // Set the status bar similarly for mouseover and focus case eMouseOver: diff --git a/dom/base/Element.h b/dom/base/Element.h index 782004703..0104d795c 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -1400,7 +1400,7 @@ protected: /** * Handle status bar updates before they can be cancelled. */ - nsresult PreHandleEventForLinks(EventChainPreVisitor& aVisitor); + nsresult GetEventTargetParentForLinks(EventChainPreVisitor& aVisitor); /** * Handle default actions for link event if the event isn't consumed yet. diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp index 526c3c9d4..ca00a49a5 100644 --- a/dom/base/FragmentOrElement.cpp +++ b/dom/base/FragmentOrElement.cpp @@ -718,7 +718,7 @@ FindChromeAccessOnlySubtreeOwner(nsIContent* aContent) } nsresult -nsIContent::PreHandleEvent(EventChainPreVisitor& aVisitor) +nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor) { //FIXME! Document how this event retargeting works, Bug 329124. aVisitor.mCanHandle = true; diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index b05bf827b..45c80ca7f 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -7712,7 +7712,7 @@ nsDocument::GetExistingListenerManager() const } nsresult -nsDocument::PreHandleEvent(EventChainPreVisitor& aVisitor) +nsDocument::GetEventTargetParent(EventChainPreVisitor& aVisitor) { aVisitor.mCanHandle = true; // FIXME! This is a hack to make middle mouse paste working also in Editor. diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h index 90e511dcb..79b7f18f4 100644 --- a/dom/base/nsDocument.h +++ b/dom/base/nsDocument.h @@ -810,7 +810,7 @@ public: NS_DECL_NSIDOMDOCUMENTXBL // nsIDOMEventTarget - virtual nsresult PreHandleEvent( + virtual nsresult GetEventTargetParent( mozilla::EventChainPreVisitor& aVisitor) override; virtual mozilla::EventListenerManager* GetOrCreateListenerManager() override; diff --git a/dom/base/nsGenConImageContent.cpp b/dom/base/nsGenConImageContent.cpp index e1b1f5a17..af3b186bd 100644 --- a/dom/base/nsGenConImageContent.cpp +++ b/dom/base/nsGenConImageContent.cpp @@ -46,7 +46,7 @@ public: virtual void UnbindFromTree(bool aDeep, bool aNullParent) override; virtual EventStates IntrinsicState() const override; - virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override + virtual nsresult GetEventTargetParent(EventChainPreVisitor& aVisitor) override { MOZ_ASSERT(IsInNativeAnonymousSubtree()); if (aVisitor.mEvent->mMessage == eLoad || @@ -54,7 +54,7 @@ public: // Don't propagate the events to the parent. return NS_OK; } - return nsXMLElement::PreHandleEvent(aVisitor); + return nsXMLElement::GetEventTargetParent(aVisitor); } private: diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index c965d5b97..802b44f38 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -3577,9 +3577,10 @@ nsGlobalWindow::WillHandleEvent(EventChainPostVisitor& aVisitor) } nsresult -nsGlobalWindow::PreHandleEvent(EventChainPreVisitor& aVisitor) +nsGlobalWindow::GetEventTargetParent(EventChainPreVisitor& aVisitor) { - NS_PRECONDITION(IsInnerWindow(), "PreHandleEvent is used on outer window!?"); + NS_PRECONDITION(IsInnerWindow(), + "GetEventTargetParent is used on outer window!?"); EventMessage msg = aVisitor.mEvent->mMessage; aVisitor.mCanHandle = true; @@ -3812,7 +3813,7 @@ nsGlobalWindow::PostHandleEvent(EventChainPostVisitor& aVisitor) } else if (aVisitor.mEvent->mMessage == eLoad && aVisitor.mEvent->IsTrusted()) { // This is page load event since load events don't propagate to |window|. - // @see nsDocument::PreHandleEvent. + // @see nsDocument::GetEventTargetParent. mIsDocumentLoaded = true; nsCOMPtr element = GetOuterWindow()->GetFrameElementInternal(); diff --git a/dom/base/nsIContent.h b/dom/base/nsIContent.h index dcdc632b4..e179d6ebc 100644 --- a/dom/base/nsIContent.h +++ b/dom/base/nsIContent.h @@ -947,7 +947,7 @@ public: // Overloaded from nsINode virtual already_AddRefed GetBaseURI(bool aTryUseXHRDocBaseURI = false) const override; - virtual nsresult PreHandleEvent( + virtual nsresult GetEventTargetParent( mozilla::EventChainPreVisitor& aVisitor) override; virtual bool IsPurple() = 0; diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp index 212110b72..0b56f519d 100644 --- a/dom/base/nsINode.cpp +++ b/dom/base/nsINode.cpp @@ -1243,7 +1243,7 @@ nsINode::RemoveEventListener(const nsAString& aType, NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsINode) nsresult -nsINode::PreHandleEvent(EventChainPreVisitor& aVisitor) +nsINode::GetEventTargetParent(EventChainPreVisitor& aVisitor) { // This is only here so that we can use the NS_DECL_NSIDOMTARGET macro NS_ABORT(); diff --git a/dom/base/nsInProcessTabChildGlobal.cpp b/dom/base/nsInProcessTabChildGlobal.cpp index 10ccf4aec..547bb8d36 100644 --- a/dom/base/nsInProcessTabChildGlobal.cpp +++ b/dom/base/nsInProcessTabChildGlobal.cpp @@ -97,7 +97,7 @@ nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell, mozilla::HoldJSObjects(this); // If owner corresponds to an