зеркало из https://github.com/mozilla/gecko-dev.git
backout 387a5f8b5e4f and b45a4dcb88c1
This commit is contained in:
Родитель
acda0615b5
Коммит
a354f49b88
|
@ -5652,23 +5652,6 @@ AppendToTouchList(const uint32_t& aKey, nsCOMPtr<nsIDOMTouch>& aData, void *aTou
|
|||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
FindAnyTarget(const uint32_t& aKey, nsCOMPtr<nsIDOMTouch>& aData,
|
||||
void* aAnyTarget)
|
||||
{
|
||||
if (aData) {
|
||||
nsCOMPtr<nsIDOMEventTarget> target;
|
||||
aData->GetTarget(getter_AddRefs(target));
|
||||
if (target) {
|
||||
nsCOMPtr<nsIContent>* content =
|
||||
static_cast<nsCOMPtr<nsIContent>*>(aAnyTarget);
|
||||
*content = do_QueryInterface(target);
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsIFrame* GetNearestFrameContainingPresShell(nsIPresShell* aPresShell)
|
||||
{
|
||||
nsIView* view = aPresShell->GetViewManager()->GetRootView();
|
||||
|
@ -5872,6 +5855,7 @@ PresShell::HandleEvent(nsIFrame *aFrame,
|
|||
if (!captureRetarget && !isWindowLevelMouseExit) {
|
||||
nsPoint eventPoint;
|
||||
if (aEvent->message == NS_TOUCH_START) {
|
||||
// Add any new touches to the queue
|
||||
nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
|
||||
// if there is only one touch in this touchstart event, assume that it is
|
||||
// the start of a new touch session and evict any old touches in the
|
||||
|
@ -5883,19 +5867,7 @@ PresShell::HandleEvent(nsIFrame *aFrame,
|
|||
EvictTouchPoint(touches[i]);
|
||||
}
|
||||
}
|
||||
// if this is a continuing session, ensure that all these events are
|
||||
// in the same document by taking the target of the events already in
|
||||
// the capture list
|
||||
nsCOMPtr<nsIContent> anyTarget;
|
||||
if (gCaptureTouchList.Count() > 0) {
|
||||
gCaptureTouchList.Enumerate(&FindAnyTarget, &anyTarget);
|
||||
} else {
|
||||
gPreventMouseEvents = false;
|
||||
}
|
||||
|
||||
// Add any new touches to the queue
|
||||
for (int32_t i = touchEvent->touches.Length(); i; ) {
|
||||
--i;
|
||||
for (uint32_t i = 0; i < touchEvent->touches.Length(); ++i) {
|
||||
nsIDOMTouch *touch = touchEvent->touches[i];
|
||||
nsDOMTouch *domtouch = static_cast<nsDOMTouch*>(touch);
|
||||
touch->mMessage = aEvent->message;
|
||||
|
@ -5906,59 +5878,9 @@ PresShell::HandleEvent(nsIFrame *aFrame,
|
|||
// This event is a new touch. Mark it as a changedTouch and
|
||||
// add it to the queue.
|
||||
touch->mChanged = true;
|
||||
gCaptureTouchList.Put(id, touch);
|
||||
|
||||
// find the target for this touch
|
||||
uint32_t flags = 0;
|
||||
eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent,
|
||||
touch->mRefPoint,
|
||||
frame);
|
||||
nsIFrame* target =
|
||||
FindFrameTargetedByInputEvent(aEvent->eventStructType,
|
||||
frame,
|
||||
eventPoint,
|
||||
flags);
|
||||
if (target && !anyTarget) {
|
||||
target->GetContentForEvent(aEvent, getter_AddRefs(anyTarget));
|
||||
while (anyTarget && !anyTarget->IsElement()) {
|
||||
anyTarget = anyTarget->GetParent();
|
||||
}
|
||||
domtouch->SetTarget(anyTarget);
|
||||
gCaptureTouchList.Put(id, touch);
|
||||
} else {
|
||||
nsIFrame* newTargetFrame = nullptr;
|
||||
for (nsIFrame* f = target; f;
|
||||
f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) {
|
||||
if (f->PresContext()->Document() == anyTarget->OwnerDoc()) {
|
||||
newTargetFrame = f;
|
||||
break;
|
||||
}
|
||||
// We must be in a subdocument so jump directly to the root frame.
|
||||
// GetParentOrPlaceholderForCrossDoc gets called immediately to
|
||||
// jump up to the containing document.
|
||||
f = f->PresContext()->GetPresShell()->GetRootFrame();
|
||||
}
|
||||
|
||||
// if we couldn't find a target frame in the same document as
|
||||
// anyTarget, remove the touch from the capture touch list, as
|
||||
// well as the event->touches array. touchmove events that aren't
|
||||
// in the captured touch list will be discarded
|
||||
if (!newTargetFrame) {
|
||||
touchEvent->touches.RemoveElementAt(i);
|
||||
} else {
|
||||
target = newTargetFrame;
|
||||
nsCOMPtr<nsIContent> targetContent;
|
||||
target->GetContentForEvent(aEvent, getter_AddRefs(targetContent));
|
||||
while (targetContent && !targetContent->IsElement()) {
|
||||
targetContent = targetContent->GetParent();
|
||||
}
|
||||
touch->SetTarget(targetContent);
|
||||
gCaptureTouchList.Put(id, touch);
|
||||
}
|
||||
}
|
||||
|
||||
if (target) {
|
||||
frame = target;
|
||||
}
|
||||
eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, touch->mRefPoint, frame);
|
||||
} else {
|
||||
// This touch is an old touch, we need to ensure that is not
|
||||
// marked as changed and set its target correctly
|
||||
|
@ -6029,6 +5951,47 @@ PresShell::HandleEvent(nsIFrame *aFrame,
|
|||
PresShell* shell =
|
||||
static_cast<PresShell*>(frame->PresContext()->PresShell());
|
||||
|
||||
switch (aEvent->message) {
|
||||
case NS_TOUCH_MOVE:
|
||||
case NS_TOUCH_CANCEL:
|
||||
case NS_TOUCH_END: {
|
||||
// Remove the changed touches
|
||||
// need to make sure we only remove touches that are ending here
|
||||
nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
|
||||
nsTArray<nsCOMPtr<nsIDOMTouch> > &touches = touchEvent->touches;
|
||||
for (uint32_t i = 0; i < touches.Length(); ++i) {
|
||||
nsIDOMTouch *touch = touches[i];
|
||||
if (!touch) {
|
||||
break;
|
||||
}
|
||||
|
||||
int32_t id;
|
||||
touch->GetIdentifier(&id);
|
||||
nsCOMPtr<nsIDOMTouch> oldTouch;
|
||||
gCaptureTouchList.Get(id, getter_AddRefs(oldTouch));
|
||||
if (!oldTouch) {
|
||||
break;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMEventTarget> targetPtr;
|
||||
oldTouch->GetTarget(getter_AddRefs(targetPtr));
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(targetPtr);
|
||||
if (!content) {
|
||||
break;
|
||||
}
|
||||
|
||||
nsIFrame* contentFrame = content->GetPrimaryFrame();
|
||||
if (!contentFrame) {
|
||||
break;
|
||||
}
|
||||
|
||||
shell = static_cast<PresShell*>(
|
||||
contentFrame->PresContext()->PresShell());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we have an active EventStateManager which isn't the
|
||||
// EventStateManager of the current PresContext.
|
||||
// If that is the case, and mouse is over some ancestor document,
|
||||
|
@ -6391,10 +6354,9 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsEventStatus* aStatus)
|
|||
case NS_TOUCH_MOVE: {
|
||||
// Check for touches that changed. Mark them add to queue
|
||||
nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
|
||||
nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
|
||||
nsTArray<nsCOMPtr<nsIDOMTouch> > touches = touchEvent->touches;
|
||||
bool haveChanged = false;
|
||||
for (int32_t i = touches.Length(); i; ) {
|
||||
--i;
|
||||
for (uint32_t i = 0; i < touches.Length(); ++i) {
|
||||
nsIDOMTouch *touch = touches[i];
|
||||
nsDOMTouch *domtouch = static_cast<nsDOMTouch*>(touch);
|
||||
if (!touch) {
|
||||
|
@ -6407,7 +6369,6 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsEventStatus* aStatus)
|
|||
nsCOMPtr<nsIDOMTouch> oldTouch;
|
||||
gCaptureTouchList.Get(id, getter_AddRefs(oldTouch));
|
||||
if (!oldTouch) {
|
||||
touches.RemoveElementAt(i);
|
||||
continue;
|
||||
}
|
||||
if(domtouch->Equals(oldTouch)) {
|
||||
|
@ -6417,10 +6378,6 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsEventStatus* aStatus)
|
|||
|
||||
nsCOMPtr<nsPIDOMEventTarget> targetPtr;
|
||||
oldTouch->GetTarget(getter_AddRefs(targetPtr));
|
||||
if (!targetPtr) {
|
||||
touches.RemoveElementAt(i);
|
||||
continue;
|
||||
}
|
||||
domtouch->SetTarget(targetPtr);
|
||||
|
||||
gCaptureTouchList.Put(id, touch);
|
||||
|
@ -6552,6 +6509,7 @@ PresShell::DispatchTouchEvent(nsEvent *aEvent,
|
|||
nsPresShellEventCB* aEventCB,
|
||||
bool aTouchIsNew)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
// calling preventDefault on touchstart or the first touchmove for a
|
||||
// point prevents mouse events
|
||||
bool canPrevent = aEvent->message == NS_TOUCH_START ||
|
||||
|
@ -6559,56 +6517,85 @@ PresShell::DispatchTouchEvent(nsEvent *aEvent,
|
|||
bool preventDefault = false;
|
||||
nsEventStatus tmpStatus = nsEventStatus_eIgnore;
|
||||
nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
|
||||
|
||||
// loop over all touches and dispatch events on any that have changed
|
||||
for (uint32_t i = 0; i < touchEvent->touches.Length(); ++i) {
|
||||
nsIDOMTouch *touch = touchEvent->touches[i];
|
||||
if (!touch || !touch->mChanged) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMEventTarget> targetPtr;
|
||||
touch->GetTarget(getter_AddRefs(targetPtr));
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(targetPtr);
|
||||
if (!content) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsIContent* capturingContent = GetCapturingContent();
|
||||
if (capturingContent) {
|
||||
if (capturingContent->OwnerDoc() != content->OwnerDoc()) {
|
||||
// Wrong document, don't dispatch anything.
|
||||
// touch events should fire on all targets
|
||||
if (aEvent->message != NS_TOUCH_START) {
|
||||
for (uint32_t i = 0; i < touchEvent->touches.Length(); ++i) {
|
||||
nsIDOMTouch *touch = touchEvent->touches[i];
|
||||
if (!touch || !touch->mChanged) {
|
||||
continue;
|
||||
}
|
||||
// copy the event
|
||||
nsCOMPtr<nsPIDOMEventTarget> targetPtr;
|
||||
touch->GetTarget(getter_AddRefs(targetPtr));
|
||||
if (!targetPtr) {
|
||||
continue;
|
||||
}
|
||||
content = capturingContent;
|
||||
}
|
||||
// copy the event
|
||||
nsTouchEvent newEvent(NS_IS_TRUSTED_EVENT(touchEvent) ?
|
||||
true : false,
|
||||
touchEvent);
|
||||
newEvent.target = targetPtr;
|
||||
|
||||
nsRefPtr<PresShell> contentPresShell;
|
||||
if (content->OwnerDoc() == mDocument) {
|
||||
contentPresShell = static_cast<PresShell*>
|
||||
(content->OwnerDoc()->GetShell());
|
||||
nsTouchEvent newEvent(NS_IS_TRUSTED_EVENT(touchEvent) ?
|
||||
true : false,
|
||||
touchEvent);
|
||||
newEvent.target = targetPtr;
|
||||
|
||||
// If someone is capturing, all touch events are filtered to their target
|
||||
nsCOMPtr<nsIContent> content = GetCapturingContent();
|
||||
|
||||
// if no one is capturing, set the capturing target
|
||||
if (!content) {
|
||||
content = do_QueryInterface(targetPtr);
|
||||
}
|
||||
nsRefPtr<PresShell> contentPresShell;
|
||||
if (content && content->OwnerDoc() == mDocument) {
|
||||
contentPresShell = static_cast<PresShell*>
|
||||
(content->OwnerDoc()->GetShell());
|
||||
if (contentPresShell) {
|
||||
contentPresShell->PushCurrentEventInfo(
|
||||
content->GetPrimaryFrame(), content);
|
||||
}
|
||||
}
|
||||
nsPresContext *context = nsContentUtils::GetContextForContent(content);
|
||||
if (!context) {
|
||||
context = mPresContext;
|
||||
}
|
||||
tmpStatus = nsEventStatus_eIgnore;
|
||||
nsEventDispatcher::Dispatch(targetPtr, context,
|
||||
&newEvent, nullptr, &tmpStatus, aEventCB);
|
||||
if (nsEventStatus_eConsumeNoDefault == tmpStatus) {
|
||||
preventDefault = true;
|
||||
}
|
||||
if (contentPresShell) {
|
||||
//XXXsmaug huge hack. Pushing possibly capturing content,
|
||||
// even though event target is something else.
|
||||
contentPresShell->PushCurrentEventInfo(
|
||||
content->GetPrimaryFrame(), content);
|
||||
contentPresShell->PopCurrentEventInfo();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// touchevents need to have the target attribute set on each touch
|
||||
for (uint32_t i = 0; i < touchEvent->touches.Length(); ++i) {
|
||||
nsIDOMTouch *touch = touchEvent->touches[i];
|
||||
if (touch->mChanged) {
|
||||
touch->SetTarget(mCurrentEventContent);
|
||||
}
|
||||
}
|
||||
|
||||
if (mCurrentEventContent) {
|
||||
nsEventDispatcher::Dispatch(mCurrentEventContent, mPresContext,
|
||||
aEvent, nullptr, &tmpStatus, aEventCB);
|
||||
} else {
|
||||
nsCOMPtr<nsIContent> targetContent;
|
||||
rv = mCurrentEventFrame->GetContentForEvent(aEvent,
|
||||
getter_AddRefs(targetContent));
|
||||
if (NS_SUCCEEDED(rv) && targetContent) {
|
||||
nsEventDispatcher::Dispatch(targetContent, mPresContext, aEvent,
|
||||
nullptr, &tmpStatus, aEventCB);
|
||||
} else if (mDocument) {
|
||||
nsEventDispatcher::Dispatch(mDocument, mPresContext, aEvent,
|
||||
nullptr, &tmpStatus, nullptr);
|
||||
}
|
||||
}
|
||||
nsPresContext *context = nsContentUtils::GetContextForContent(content);
|
||||
tmpStatus = nsEventStatus_eIgnore;
|
||||
nsEventDispatcher::Dispatch(targetPtr, context,
|
||||
&newEvent, nullptr, &tmpStatus, aEventCB);
|
||||
if (nsEventStatus_eConsumeNoDefault == tmpStatus) {
|
||||
preventDefault = true;
|
||||
}
|
||||
|
||||
if (contentPresShell) {
|
||||
contentPresShell->PopCurrentEventInfo();
|
||||
if (touchEvent->touches.Length() == 1) {
|
||||
gPreventMouseEvents = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче