Bug 369644, make mouseover/out handle native anonymous content properly, r=jst, sr=sicking

This commit is contained in:
Olli.Pettay%helsinki.fi 2007-05-13 13:59:00 +00:00
Родитель 6a0f30665e
Коммит 921d3b7fe0
2 изменённых файлов: 60 добавлений и 2 удалений

Просмотреть файл

@ -1857,14 +1857,65 @@ nsGenericElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
return nsGenericElement::doPreHandleEvent(this, aVisitor);
}
static nsIContent*
FindFirstNonAnonContent(nsIContent* aContent)
{
while (aContent && aContent->IsAnonymousForEvents()) {
aContent = aContent->GetParent();
}
return aContent;
}
static PRBool
IsInAnonContent(nsIContent* aContent)
{
while (aContent && !aContent->IsAnonymousForEvents()) {
aContent = aContent->GetParent();
}
return !!aContent;
}
nsresult
nsGenericElement::doPreHandleEvent(nsIContent* aContent,
nsEventChainPreVisitor& aVisitor)
{
//FIXME! Document how this event retargeting works, Bug 329124.
aVisitor.mCanHandle = PR_TRUE;
// Don't propagate mouseover and mouseout events when mouse is moving
// inside native anonymous content.
PRBool isAnonForEvents = aContent->IsAnonymousForEvents();
if (aVisitor.mEvent->message == NS_MOUSE_ENTER_SYNTH ||
aVisitor.mEvent->message == NS_MOUSE_EXIT_SYNTH) {
nsCOMPtr<nsIContent> relatedTarget =
do_QueryInterface(NS_STATIC_CAST(nsMouseEvent*,
aVisitor.mEvent)->relatedTarget);
if (relatedTarget &&
relatedTarget->GetOwnerDoc() == aContent->GetOwnerDoc()) {
// If current target is anonymous for events or we know that related
// target is descendant of an element which is anonymous for events,
// we may want to stop event propagation.
// If aContent is the original target, aVisitor.mRelatedTargetIsInAnon
// must be updated.
if (isAnonForEvents || aVisitor.mRelatedTargetIsInAnon ||
(aVisitor.mEvent->originalTarget == aContent &&
(aVisitor.mRelatedTargetIsInAnon = IsInAnonContent(relatedTarget)))) {
nsIContent* nonAnon = FindFirstNonAnonContent(aContent);
nsIContent* nonAnonRelated = FindFirstNonAnonContent(relatedTarget);
if (nonAnon == nonAnonRelated ||
nsContentUtils::ContentIsDescendantOf(nonAnonRelated, nonAnon)) {
aVisitor.mParentTarget = nsnull;
// Event should not propagate to non-anon content.
aVisitor.mCanHandle = isAnonForEvents;
return NS_OK;
}
}
}
}
nsCOMPtr<nsIContent> parent = aContent->GetParent();
if (aContent->IsAnonymousForEvents()) {
if (isAnonForEvents) {
// Don't propagate mutation events which are dispatched somewhere inside
// native anonymous content.
if (aVisitor.mEvent->eventStructType == NS_MUTATION_EVENT) {

Просмотреть файл

@ -131,7 +131,8 @@ public:
nsIDOMEvent* aDOMEvent,
nsEventStatus aEventStatus = nsEventStatus_eIgnore)
: nsEventChainVisitor(aPresContext, aEvent, aDOMEvent, aEventStatus),
mCanHandle(PR_TRUE), mForceContentDispatch(PR_FALSE) {}
mCanHandle(PR_TRUE), mForceContentDispatch(PR_FALSE),
mRelatedTargetIsInAnon(PR_FALSE) {}
void Reset() {
mItemFlags = 0;
@ -157,6 +158,12 @@ public:
*/
PRPackedBool mForceContentDispatch;
/**
* PR_TRUE if it is known that related target is or is a descendant of an
* element which is anonymous for events.
*/
PRPackedBool mRelatedTargetIsInAnon;
/**
* Parent item in the event target chain.
*/