nsresult HTMLButtonElement::PostHandleEvent(EventChainPostVisitor& aVisitor) { nsresult rv = NS_OK; if (!aVisitor.mPresContext) { return rv; } if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault) { WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent(); if (mouseEvent && mouseEvent->IsLeftClickEvent()) { // DOMActive event should be trusted since the activation is actually // occurred even if the cause is an untrusted click event. InternalUIEvent actEvent(true, eLegacyDOMActivate, mouseEvent); actEvent.mDetail = 1; nsCOMPtr<nsIPresShell> shell = aVisitor.mPresContext->GetPresShell(); if (shell) { nsEventStatus status = nsEventStatus_eIgnore; mInInternalActivate = true; shell->HandleDOMEventWithTarget(this, &actEvent, &status); mInInternalActivate = false; // If activate is cancelled, we must do the same as when click is // cancelled (revert the checkbox to its original value). if (status == nsEventStatus_eConsumeNoDefault) { aVisitor.mEventStatus = status; } } } } // mForm is null if the event handler removed us from the document (bug 194582). if ((aVisitor.mItemFlags & NS_IN_SUBMIT_CLICK) && mForm) { // tell the form that we are about to exit a click handler // so the form knows not to defer subsequent submissions // the pending ones that were created during the handler // will be flushed or forgoten. mForm->OnSubmitClickEnd(); } if (nsEventStatus_eIgnore == aVisitor.mEventStatus) { switch (aVisitor.mEvent->mMessage) { case eKeyPress: case eKeyUp: { // For backwards compat, trigger buttons with space or enter // (bug 25300) WidgetKeyboardEvent* keyEvent = aVisitor.mEvent->AsKeyboardEvent(); if ((keyEvent->mKeyCode == NS_VK_RETURN && eKeyPress == aVisitor.mEvent->mMessage) || (keyEvent->mKeyCode == NS_VK_SPACE && eKeyUp == aVisitor.mEvent->mMessage)) { DispatchSimulatedClick(this, aVisitor.mEvent->IsTrusted(), aVisitor.mPresContext); aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault; } } break; default: break; } if (aVisitor.mItemFlags & NS_OUTER_ACTIVATE_EVENT) { if (mForm && (mType == NS_FORM_BUTTON_SUBMIT || mType == NS_FORM_BUTTON_RESET)) { InternalFormEvent event(true, (mType == NS_FORM_BUTTON_RESET) ? eFormReset : eFormSubmit); event.mOriginator = this; nsEventStatus status = nsEventStatus_eIgnore; nsCOMPtr<nsIPresShell> presShell = aVisitor.mPresContext->GetPresShell(); // If |nsIPresShell::Destroy| has been called due to // handling the event, the pres context will return // a null pres shell. See bug 125624. // // Using presShell to dispatch the event. It makes sure that // event is not handled if the window is being destroyed. if (presShell && (event.mMessage != eFormSubmit || mForm->SubmissionCanProceed(this))) { // TODO: removing this code and have the submit event sent by the form // see bug 592124. // Hold a strong ref while dispatching RefPtr<HTMLFormElement> form(mForm); presShell->HandleDOMEventWithTarget(form, &event, &status); aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault; } } } } else if ((aVisitor.mItemFlags & NS_IN_SUBMIT_CLICK) && mForm) { // Tell the form to flush a possible pending submission. // the reason is that the script returned false (the event was // not ignored) so if there is a stored submission, it needs to // be submitted immediatelly. // Note, NS_IN_SUBMIT_CLICK is set only when we're in outer activate event. mForm->FlushPendingSubmission(); } //if return rv; }
nsresult HTMLButtonElement::PostHandleEvent(EventChainPostVisitor& aVisitor) { nsresult rv = NS_OK; if (!aVisitor.mPresContext) { return rv; } if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault) { WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent(); if (mouseEvent && mouseEvent->IsLeftClickEvent()) { // DOMActive event should be trusted since the activation is actually // occurred even if the cause is an untrusted click event. InternalUIEvent actEvent(true, eLegacyDOMActivate, mouseEvent); actEvent.mDetail = 1; nsCOMPtr<nsIPresShell> shell = aVisitor.mPresContext->GetPresShell(); if (shell) { nsEventStatus status = nsEventStatus_eIgnore; mInInternalActivate = true; shell->HandleDOMEventWithTarget(this, &actEvent, &status); mInInternalActivate = false; // If activate is cancelled, we must do the same as when click is // cancelled (revert the checkbox to its original value). if (status == nsEventStatus_eConsumeNoDefault) { aVisitor.mEventStatus = status; } } } } // mForm is null if the event handler removed us from the document (bug 194582). if ((aVisitor.mItemFlags & NS_IN_SUBMIT_CLICK) && mForm) { // tell the form that we are about to exit a click handler // so the form knows not to defer subsequent submissions // the pending ones that were created during the handler // will be flushed or forgoten. mForm->OnSubmitClickEnd(); } if (nsEventStatus_eIgnore == aVisitor.mEventStatus) { switch (aVisitor.mEvent->mMessage) { case eKeyPress: case eKeyUp: { // For backwards compat, trigger buttons with space or enter // (bug 25300) WidgetKeyboardEvent* keyEvent = aVisitor.mEvent->AsKeyboardEvent(); if ((keyEvent->mKeyCode == NS_VK_RETURN && eKeyPress == aVisitor.mEvent->mMessage) || (keyEvent->mKeyCode == NS_VK_SPACE && eKeyUp == aVisitor.mEvent->mMessage)) { DispatchSimulatedClick(this, aVisitor.mEvent->IsTrusted(), aVisitor.mPresContext); aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault; } } break; case eMouseDown: { WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent(); if (mouseEvent->button == WidgetMouseEvent::eLeftButton) { if (mouseEvent->IsTrusted()) { EventStateManager* esm = aVisitor.mPresContext->EventStateManager(); EventStateManager::SetActiveManager( static_cast<EventStateManager*>(esm), this); } nsIFocusManager* fm = nsFocusManager::GetFocusManager(); if (fm) { uint32_t flags = nsIFocusManager::FLAG_BYMOUSE | nsIFocusManager::FLAG_NOSCROLL; // If this was a touch-generated event, pass that information: if (mouseEvent->inputSource == nsIDOMMouseEvent::MOZ_SOURCE_TOUCH) { flags |= nsIFocusManager::FLAG_BYTOUCH; } fm->SetFocus(this, flags); } mouseEvent->mFlags.mMultipleActionsPrevented = true; } else if (mouseEvent->button == WidgetMouseEvent::eMiddleButton || mouseEvent->button == WidgetMouseEvent::eRightButton) { // cancel all of these events for buttons //XXXsmaug What to do with these events? Why these should be cancelled? if (aVisitor.mDOMEvent) { aVisitor.mDOMEvent->StopPropagation(); } } } break; // cancel all of these events for buttons //XXXsmaug What to do with these events? Why these should be cancelled? case eMouseUp: case eMouseDoubleClick: { WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent(); if (aVisitor.mDOMEvent && (mouseEvent->button == WidgetMouseEvent::eMiddleButton || mouseEvent->button == WidgetMouseEvent::eRightButton)) { aVisitor.mDOMEvent->StopPropagation(); } } break; case eMouseOver: { aVisitor.mPresContext->EventStateManager()-> SetContentState(this, NS_EVENT_STATE_HOVER); aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault; } break; // XXX this doesn't seem to do anything yet case eMouseOut: { aVisitor.mPresContext->EventStateManager()-> SetContentState(nullptr, NS_EVENT_STATE_HOVER); aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault; } break; default: break; } if (aVisitor.mItemFlags & NS_OUTER_ACTIVATE_EVENT) { if (mForm && (mType == NS_FORM_BUTTON_SUBMIT || mType == NS_FORM_BUTTON_RESET)) { InternalFormEvent event(true, (mType == NS_FORM_BUTTON_RESET) ? eFormReset : eFormSubmit); event.originator = this; nsEventStatus status = nsEventStatus_eIgnore; nsCOMPtr<nsIPresShell> presShell = aVisitor.mPresContext->GetPresShell(); // If |nsIPresShell::Destroy| has been called due to // handling the event, the pres context will return // a null pres shell. See bug 125624. // // Using presShell to dispatch the event. It makes sure that // event is not handled if the window is being destroyed. if (presShell && (event.mMessage != eFormSubmit || mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate) || // We know the element is a submit control, if this check is moved, // make sure formnovalidate is used only if it's a submit control. HasAttr(kNameSpaceID_None, nsGkAtoms::formnovalidate) || mForm->CheckValidFormSubmission())) { // TODO: removing this code and have the submit event sent by the form // see bug 592124. // Hold a strong ref while dispatching RefPtr<HTMLFormElement> form(mForm); presShell->HandleDOMEventWithTarget(mForm, &event, &status); aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault; } } } } else if ((aVisitor.mItemFlags & NS_IN_SUBMIT_CLICK) && mForm) { // Tell the form to flush a possible pending submission. // the reason is that the script returned false (the event was // not ignored) so if there is a stored submission, it needs to // be submitted immediatelly. // Note, NS_IN_SUBMIT_CLICK is set only when we're in outer activate event. mForm->FlushPendingSubmission(); } //if return rv; }