Bug 1305458 Part7: Refine nsXULElement::GetEventTargetParent. r=smaug

MozReview-Commit-ID: 7ubVChOb04x

--HG--
extra : rebase_source : badbfb7238dcd08870065a4650e50e2c486fefab
This commit is contained in:
Stone Shih 2016-10-18 16:55:26 +08:00
Родитель 8400e13089
Коммит 0d5527c8ef
2 изменённых файлов: 63 добавлений и 48 удалений

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

@ -1268,17 +1268,65 @@ nsXULElement::List(FILE* out, int32_t aIndent) const
}
#endif
bool
nsXULElement::IsEventStoppedFromAnonymousScrollbar(EventMessage aMessage)
{
return (IsRootOfNativeAnonymousSubtree() &&
IsAnyOfXULElements(nsGkAtoms::scrollbar, nsGkAtoms::scrollcorner) &&
(aMessage == eMouseClick || aMessage == eMouseDoubleClick ||
aMessage == eXULCommand || aMessage == eContextMenu ||
aMessage == eDragStart));
}
nsresult
nsXULElement::DispatchXULCommand(const EventChainPreVisitor& aVisitor,
nsAutoString& aCommand)
{
// XXX sXBL/XBL2 issue! Owner or current document?
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(GetUncomposedDoc()));
NS_ENSURE_STATE(domDoc);
nsCOMPtr<nsIDOMElement> commandElt;
domDoc->GetElementById(aCommand, getter_AddRefs(commandElt));
nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
if (commandContent) {
// Create a new command event to dispatch to the element
// pointed to by the command attribute. The new event's
// sourceEvent will be the original command event that we're
// handling.
nsCOMPtr<nsIDOMEvent> domEvent = aVisitor.mDOMEvent;
while (domEvent) {
Event* event = domEvent->InternalDOMEvent();
NS_ENSURE_STATE(!SameCOMIdentity(event->GetOriginalTarget(),
commandContent));
nsCOMPtr<nsIDOMXULCommandEvent> commandEvent =
do_QueryInterface(domEvent);
if (commandEvent) {
commandEvent->GetSourceEvent(getter_AddRefs(domEvent));
} else {
domEvent = nullptr;
}
}
WidgetInputEvent* orig = aVisitor.mEvent->AsInputEvent();
nsContentUtils::DispatchXULCommand(
commandContent,
orig->IsTrusted(),
aVisitor.mDOMEvent,
nullptr,
orig->IsControl(),
orig->IsAlt(),
orig->IsShift(),
orig->IsMeta());
} else {
NS_WARNING("A XUL element is attached to a command that doesn't exist!\n");
}
return NS_OK;
}
nsresult
nsXULElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
aVisitor.mForceContentDispatch = true; //FIXME! Bug 329119
if (IsRootOfNativeAnonymousSubtree() &&
(IsAnyOfXULElements(nsGkAtoms::scrollbar, nsGkAtoms::scrollcorner)) &&
(aVisitor.mEvent->mMessage == eMouseClick ||
aVisitor.mEvent->mMessage == eMouseDoubleClick ||
aVisitor.mEvent->mMessage == eXULCommand ||
aVisitor.mEvent->mMessage == eContextMenu ||
aVisitor.mEvent->mMessage == eDragStart)) {
if (IsEventStoppedFromAnonymousScrollbar(aVisitor.mEvent->mMessage)) {
// Don't propagate these events from native anonymous scrollbar.
aVisitor.mCanHandle = true;
aVisitor.mParentTarget = nullptr;
@ -1295,52 +1343,14 @@ nsXULElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
// See if we have a command elt. If so, we execute on the command
// instead of on our content element.
nsAutoString command;
if (xulEvent && GetAttr(kNameSpaceID_None, nsGkAtoms::command, command) &&
if (xulEvent &&
GetAttr(kNameSpaceID_None, nsGkAtoms::command, command) &&
!command.IsEmpty()) {
// Stop building the event target chain for the original event.
// We don't want it to propagate to any DOM nodes.
aVisitor.mCanHandle = false;
aVisitor.mAutomaticChromeDispatch = false;
// XXX sXBL/XBL2 issue! Owner or current document?
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(GetUncomposedDoc()));
NS_ENSURE_STATE(domDoc);
nsCOMPtr<nsIDOMElement> commandElt;
domDoc->GetElementById(command, getter_AddRefs(commandElt));
nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
if (commandContent) {
// Create a new command event to dispatch to the element
// pointed to by the command attribute. The new event's
// sourceEvent will be the original command event that we're
// handling.
nsCOMPtr<nsIDOMEvent> domEvent = aVisitor.mDOMEvent;
while (domEvent) {
Event* event = domEvent->InternalDOMEvent();
NS_ENSURE_STATE(!SameCOMIdentity(event->GetOriginalTarget(),
commandContent));
nsCOMPtr<nsIDOMXULCommandEvent> commandEvent =
do_QueryInterface(domEvent);
if (commandEvent) {
commandEvent->GetSourceEvent(getter_AddRefs(domEvent));
} else {
domEvent = nullptr;
}
}
WidgetInputEvent* orig = aVisitor.mEvent->AsInputEvent();
nsContentUtils::DispatchXULCommand(
commandContent,
aVisitor.mEvent->IsTrusted(),
aVisitor.mDOMEvent,
nullptr,
orig->IsControl(),
orig->IsAlt(),
orig->IsShift(),
orig->IsMeta());
} else {
NS_WARNING("A XUL element is attached to a command that doesn't exist!\n");
}
return NS_OK;
return DispatchXULCommand(aVisitor, command);
}
}

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

@ -701,6 +701,11 @@ protected:
virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
void MaybeUpdatePrivateLifetime();
bool IsEventStoppedFromAnonymousScrollbar(mozilla::EventMessage aMessage);
nsresult DispatchXULCommand(const mozilla::EventChainPreVisitor& aVisitor,
nsAutoString& aCommand);
};
#endif // nsXULElement_h__