mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-21 07:47:32 +09:00
parent
ca09afd0b0
commit
2ee3ce62fc
24 changed files with 194 additions and 131 deletions
|
|
@ -331,7 +331,7 @@ nsresult
|
|||
DOMEventTargetHelper::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
||||
{
|
||||
aVisitor.mCanHandle = true;
|
||||
aVisitor.mParentTarget = nullptr;
|
||||
aVisitor.SetParentTarget(nullptr, false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "mozilla/dom/ShadowRoot.h"
|
||||
#include "mozilla/ContentEvents.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/EventStateManager.h"
|
||||
#include "mozilla/InternalMutationEvent.h"
|
||||
#include "mozilla/dom/Performance.h"
|
||||
|
|
@ -298,6 +299,12 @@ Event::GetCurrentTarget() const
|
|||
return mEvent->GetCurrentDOMEventTarget();
|
||||
}
|
||||
|
||||
void
|
||||
Event::ComposedPath(nsTArray<RefPtr<EventTarget>>& aPath)
|
||||
{
|
||||
EventDispatcher::GetComposedPathFor(mEvent, aPath);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Event::GetCurrentTarget(nsIDOMEventTarget** aCurrentTarget)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -157,6 +157,8 @@ public:
|
|||
EventTarget* GetTarget() const;
|
||||
EventTarget* GetCurrentTarget() const;
|
||||
|
||||
void ComposedPath(nsTArray<RefPtr<EventTarget>>& aPath);
|
||||
|
||||
uint16_t EventPhase() const;
|
||||
|
||||
// xpidl implementation
|
||||
|
|
|
|||
|
|
@ -246,6 +246,36 @@ public:
|
|||
return mFlags.mPreHandleEventOnly;
|
||||
}
|
||||
|
||||
void SetRootOfClosedTree(bool aSet)
|
||||
{
|
||||
mFlags.mRootOfClosedTree = aSet;
|
||||
}
|
||||
|
||||
bool IsRootOfClosedTree()
|
||||
{
|
||||
return mFlags.mRootOfClosedTree;
|
||||
}
|
||||
|
||||
void SetIsSlotInClosedTree(bool aSet)
|
||||
{
|
||||
mFlags.mIsSlotInClosedTree = aSet;
|
||||
}
|
||||
|
||||
bool IsSlotInClosedTree()
|
||||
{
|
||||
return mFlags.mIsSlotInClosedTree;
|
||||
}
|
||||
|
||||
void SetIsChromeHandler(bool aSet)
|
||||
{
|
||||
mFlags.mIsChromeHandler = aSet;
|
||||
}
|
||||
|
||||
bool IsChromeHandler()
|
||||
{
|
||||
return mFlags.mIsChromeHandler;
|
||||
}
|
||||
|
||||
void SetMayHaveListenerManager(bool aMayHave)
|
||||
{
|
||||
mFlags.mMayHaveManager = aMayHave;
|
||||
|
|
@ -344,6 +374,9 @@ private:
|
|||
bool mIsChromeContent : 1;
|
||||
bool mWantsPreHandleEvent : 1;
|
||||
bool mPreHandleEventOnly : 1;
|
||||
bool mRootOfClosedTree : 1;
|
||||
bool mIsSlotInClosedTree : 1;
|
||||
bool mIsChromeHandler : 1;
|
||||
private:
|
||||
typedef uint32_t RawFlags;
|
||||
void SetRawFlags(RawFlags aRawFlags)
|
||||
|
|
@ -390,6 +423,7 @@ EventTargetChainItem::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
|||
SetMayHaveListenerManager(aVisitor.mMayHaveListenerManager);
|
||||
SetWantsPreHandleEvent(aVisitor.mWantsPreHandleEvent);
|
||||
SetPreHandleEventOnly(aVisitor.mWantsPreHandleEvent && !aVisitor.mCanHandle);
|
||||
SetRootOfClosedTree(aVisitor.mRootOfClosedTree);
|
||||
mItemFlags = aVisitor.mItemFlags;
|
||||
mItemData = aVisitor.mItemData;
|
||||
}
|
||||
|
|
@ -761,16 +795,19 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
|
|||
targetEtci->SetNewTarget(t);
|
||||
EventTargetChainItem* topEtci = targetEtci;
|
||||
targetEtci = nullptr;
|
||||
while (preVisitor.mParentTarget) {
|
||||
EventTarget* parentTarget = preVisitor.mParentTarget;
|
||||
while (preVisitor.GetParentTarget()) {
|
||||
EventTarget* parentTarget = preVisitor.GetParentTarget();
|
||||
EventTargetChainItem* parentEtci =
|
||||
EventTargetChainItem::Create(chain, preVisitor.mParentTarget, topEtci);
|
||||
EventTargetChainItem::Create(chain, parentTarget, topEtci);
|
||||
if (!parentEtci->IsValid()) {
|
||||
EventTargetChainItem::DestroyLast(chain, parentEtci);
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
parentEtci->SetIsSlotInClosedTree(preVisitor.mParentIsSlotInClosedTree);
|
||||
parentEtci->SetIsChromeHandler(preVisitor.mParentIsChromeHandler);
|
||||
|
||||
// Item needs event retargetting.
|
||||
if (preVisitor.mEventTargetAtParent) {
|
||||
// Need to set the target of the event
|
||||
|
|
@ -814,9 +851,13 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
|
|||
}
|
||||
// Handle the chain.
|
||||
EventChainPostVisitor postVisitor(preVisitor);
|
||||
MOZ_RELEASE_ASSERT(!aEvent->mPath);
|
||||
aEvent->mPath = &chain;
|
||||
EventTargetChainItem::HandleEventTargetChain(chain, postVisitor,
|
||||
aCallback, cd);
|
||||
|
||||
aEvent->mPath = nullptr;
|
||||
|
||||
preVisitor.mEventStatus = postVisitor.mEventStatus;
|
||||
// If the DOM event was created during event flow.
|
||||
if (!preVisitor.mDOMEvent && postVisitor.mDOMEvent) {
|
||||
|
|
@ -1128,4 +1169,64 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
EventDispatcher::GetComposedPathFor(WidgetEvent* aEvent,
|
||||
nsTArray<RefPtr<EventTarget>>& aPath)
|
||||
{
|
||||
nsTArray<EventTargetChainItem>* path = aEvent->mPath;
|
||||
if (!path || path->IsEmpty() || !aEvent->mCurrentTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
EventTarget* currentTarget =
|
||||
aEvent->mCurrentTarget->GetTargetForEventTargetChain();
|
||||
if (!currentTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoTArray<EventTarget*, 128> reversedComposedPath;
|
||||
bool hasSeenCurrentTarget = false;
|
||||
uint32_t hiddenSubtreeLevel = 0;
|
||||
for (uint32_t i = path->Length(); i; ) {
|
||||
--i;
|
||||
|
||||
EventTargetChainItem& item = path->ElementAt(i);
|
||||
if (item.PreHandleEventOnly()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!hasSeenCurrentTarget && currentTarget == item.CurrentTarget()) {
|
||||
hasSeenCurrentTarget = true;
|
||||
} else if (hasSeenCurrentTarget && item.IsRootOfClosedTree()) {
|
||||
++hiddenSubtreeLevel;
|
||||
}
|
||||
|
||||
if (hiddenSubtreeLevel == 0) {
|
||||
reversedComposedPath.AppendElement(item.CurrentTarget());
|
||||
}
|
||||
|
||||
if (item.IsSlotInClosedTree() && hiddenSubtreeLevel > 0) {
|
||||
--hiddenSubtreeLevel;
|
||||
}
|
||||
|
||||
if (item.IsChromeHandler()) {
|
||||
if (hasSeenCurrentTarget) {
|
||||
// The current behavior is to include only EventTargets from
|
||||
// either chrome side of event path or content side, not from both.
|
||||
break;
|
||||
}
|
||||
|
||||
// Need to start all over to collect the composed path on content side.
|
||||
reversedComposedPath.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
aPath.SetCapacity(reversedComposedPath.Length());
|
||||
for (uint32_t i = reversedComposedPath.Length(); i; ) {
|
||||
--i;
|
||||
aPath.AppendElement(reversedComposedPath[i]->GetTargetForDOMEvent());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
|||
|
|
@ -124,6 +124,9 @@ public:
|
|||
, mWantsWillHandleEvent(false)
|
||||
, mMayHaveListenerManager(true)
|
||||
, mWantsPreHandleEvent(false)
|
||||
, mRootOfClosedTree(false)
|
||||
, mParentIsSlotInClosedTree(false)
|
||||
, mParentIsChromeHandler(false)
|
||||
, mParentTarget(nullptr)
|
||||
, mEventTargetAtParent(nullptr)
|
||||
{
|
||||
|
|
@ -139,10 +142,26 @@ public:
|
|||
mWantsWillHandleEvent = false;
|
||||
mMayHaveListenerManager = true;
|
||||
mWantsPreHandleEvent = false;
|
||||
mRootOfClosedTree = false;
|
||||
mParentIsSlotInClosedTree = false;
|
||||
mParentIsChromeHandler = false;
|
||||
mParentTarget = nullptr;
|
||||
mEventTargetAtParent = nullptr;
|
||||
}
|
||||
|
||||
dom::EventTarget* GetParentTarget()
|
||||
{
|
||||
return mParentTarget;
|
||||
}
|
||||
|
||||
void SetParentTarget(dom::EventTarget* aParentTarget, bool aIsChromeHandler)
|
||||
{
|
||||
mParentTarget = aParentTarget;
|
||||
if (mParentTarget) {
|
||||
mParentIsChromeHandler = aIsChromeHandler;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Member that must be set in GetEventTargetParent by event targets. If set to
|
||||
* false, indicates that this event target will not be handling the event and
|
||||
|
|
@ -194,11 +213,30 @@ public:
|
|||
*/
|
||||
bool mWantsPreHandleEvent;
|
||||
|
||||
/**
|
||||
* True if the current target is either closed ShadowRoot or root of
|
||||
* chrome only access tree (for example native anonymous content).
|
||||
*/
|
||||
bool mRootOfClosedTree;
|
||||
|
||||
/**
|
||||
* True if mParentTarget is HTMLSlotElement in a closed shadow tree and the
|
||||
* current target is assigned to that slot.
|
||||
*/
|
||||
bool mParentIsSlotInClosedTree;
|
||||
|
||||
/**
|
||||
* True if mParentTarget is a chrome handler in the event path.
|
||||
*/
|
||||
bool mParentIsChromeHandler;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Parent item in the event target chain.
|
||||
*/
|
||||
dom::EventTarget* mParentTarget;
|
||||
|
||||
public:
|
||||
/**
|
||||
* If the event needs to be retargeted, this is the event target,
|
||||
* which should be used when the event is handled at mParentTarget.
|
||||
|
|
@ -281,6 +319,9 @@ public:
|
|||
WidgetEvent* aEvent,
|
||||
const nsAString& aEventType);
|
||||
|
||||
static void GetComposedPathFor(WidgetEvent* aEvent,
|
||||
nsTArray<RefPtr<dom::EventTarget>>& aPath);
|
||||
|
||||
/**
|
||||
* Called at shutting down.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue