Make labels actually fire a click on the thing they're labeling when they're

clicked, instead of just redirecting their own event.  Bug 146066, also fixes
bugs 271740 and 276279.  r=bryner, sr=jst
This commit is contained in:
bzbarsky%mit.edu 2005-01-20 16:59:42 +00:00
Родитель 27d21949cf
Коммит 1091c7b77a
3 изменённых файлов: 104 добавлений и 42 удалений

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

@ -1373,6 +1373,65 @@ IsArea(nsIContent *aContent)
aContent->IsContentOfType(nsIContent::eHTML));
}
/* static */
nsresult
nsGenericHTMLElement::DispatchEvent(nsPresContext* aPresContext,
nsEvent* aEvent,
nsIContent* aTarget,
PRBool aFullDispatch,
nsEventStatus* aStatus)
{
NS_PRECONDITION(aTarget, "Must have target");
NS_PRECONDITION(aEvent, "Must have source event");
NS_PRECONDITION(aStatus, "Null out param?");
if (!aPresContext) {
return NS_OK;
}
nsIPresShell *shell = aPresContext->GetPresShell();
if (!shell) {
return NS_OK;
}
if (aFullDispatch) {
return shell->HandleEventWithTarget(aEvent, nsnull, aTarget, NS_EVENT_FLAG_INIT,
aStatus);
}
return shell->HandleDOMEventWithTarget(aTarget, aEvent, aStatus);
}
/* static */
nsresult
nsGenericHTMLElement::DispatchClickEvent(nsPresContext* aPresContext,
nsInputEvent* aSourceEvent,
nsIContent* aTarget,
PRBool aFullDispatch,
nsEventStatus* aStatus)
{
NS_PRECONDITION(aTarget, "Must have target");
NS_PRECONDITION(aSourceEvent, "Must have source event");
NS_PRECONDITION(aStatus, "Null out param?");
nsMouseEvent event(NS_MOUSE_LEFT_CLICK, aSourceEvent->widget);
event.point = aSourceEvent->point;
event.refPoint = aSourceEvent->refPoint;
PRUint32 clickCount = 1;
if (aSourceEvent->eventStructType == NS_MOUSE_EVENT) {
clickCount = NS_STATIC_CAST(nsMouseEvent*, aSourceEvent)->clickCount;
}
event.clickCount = clickCount;
event.isShift = aSourceEvent->isShift;
event.isControl = aSourceEvent->isControl;
event.isAlt = aSourceEvent->isAlt;
event.isMeta = aSourceEvent->isMeta;
event.internalAppFlags |=
aSourceEvent->internalAppFlags & NS_APP_EVENT_FLAG_TRUSTED;
return DispatchEvent(aPresContext, &event, aTarget, aFullDispatch, aStatus);
}
nsresult
nsGenericHTMLElement::HandleDOMEventForAnchors(nsPresContext* aPresContext,
nsEvent* aEvent,
@ -1515,27 +1574,7 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsPresContext* aPresContext,
nsKeyEvent* keyEvent = NS_STATIC_CAST(nsKeyEvent*, aEvent);
if (keyEvent->keyCode == NS_VK_RETURN) {
nsEventStatus status = nsEventStatus_eIgnore;
nsCOMPtr<nsIContent> mouseContent;
//fire click
nsGUIEvent* guiEvent = NS_STATIC_CAST(nsGUIEvent*, aEvent);
nsMouseEvent event(NS_MOUSE_LEFT_CLICK, guiEvent->widget);
event.point = aEvent->point;
event.refPoint = aEvent->refPoint;
event.clickCount = 1;
event.isShift = keyEvent->isShift;
event.isControl = keyEvent->isControl;
event.isAlt = keyEvent->isAlt;
event.isMeta = keyEvent->isMeta;
event.internalAppFlags |=
aEvent->internalAppFlags & NS_APP_EVENT_FLAG_TRUSTED;
nsIPresShell *presShell = aPresContext->GetPresShell();
if (presShell) {
ret = presShell->HandleDOMEventWithTarget(this, &event, &status);
// presShell may no longer be alive, don't use it here
// unless you keep a reference.
}
ret = DispatchClickEvent(aPresContext, keyEvent, this, PR_FALSE, &status);
}
}
break;

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

@ -203,6 +203,26 @@ public:
virtual void RemoveFocus(nsPresContext *aPresContext);
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
/**
* Method to create and dispatch a left-click event loosely based on aSourceEvent. If
* aFullDispatch is true, the event will be dispatched in all event groups and so
* forth; if it's false it will be dispatched only as a DOM event.
*/
static nsresult DispatchClickEvent(nsPresContext* aPresContext,
nsInputEvent* aSourceEvent,
nsIContent* aTarget,
PRBool aFullDispatch,
nsEventStatus* aStatus);
/**
* Method to dispatch aEvent to aTarget without crashing and all.
*/
static nsresult DispatchEvent(nsPresContext* aPresContext,
nsEvent* aEvent,
nsIContent* aTarget,
PRBool aFullDispatch,
nsEventStatus* aStatus);
/**
* Standard anchor HandleDOMEvent, used by A, AREA and LINK (parameters
* are the same as HandleDOMEvent)

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

@ -217,7 +217,8 @@ nsHTMLLabelElement::HandleDOMEvent(nsPresContext* aPresContext,
*aEventStatus == nsEventStatus_eConsumeNoDefault ||
(aEvent->message != NS_MOUSE_LEFT_CLICK &&
aEvent->message != NS_FOCUS_CONTENT) ||
aFlags & NS_EVENT_FLAG_CAPTURE)
aFlags & NS_EVENT_FLAG_CAPTURE ||
!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT))
return NS_OK;
nsCOMPtr<nsIContent> content = GetForContent();
@ -225,25 +226,23 @@ nsHTMLLabelElement::HandleDOMEvent(nsPresContext* aPresContext,
mHandlingEvent = PR_TRUE;
switch (aEvent->message) {
case NS_MOUSE_LEFT_CLICK:
if (ShouldFocus(this)) {
// Focus the for content.
content->SetFocus(aPresContext);
}
if (aEvent->eventStructType == NS_MOUSE_EVENT) {
if (ShouldFocus(this)) {
// Focus the for content.
content->SetFocus(aPresContext);
}
// This sends the event twice down parts of its path. Oh well.
// This is needed for:
// * Making radio buttons and checkboxes get checked.
// * Triggering user event handlers. (For compatibility with IE,
// we do only left click. If we wanted to interpret the HTML
// spec very narrowly, we would do nothing. If we wanted to
// do something sensible, we might send more events through
// like this.) See bug 7554, bug 49897, and bug 96813.
// XXX The event should probably have its target modified. See
// bug 146066. (But what if |aDOMEvent| is null and it gets
// created later? If we forced the existence of an event and
// modified its target, we could replace |mHandlingEvent|.)
rv = content->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
// Dispatch a new click event to |content|
// (For compatibility with IE, we do only left click. If
// we wanted to interpret the HTML spec very narrowly, we
// would do nothing. If we wanted to do something
// sensible, we might send more events through like
// this.) See bug 7554, bug 49897, and bug 96813.
nsEventStatus status = *aEventStatus;
rv = DispatchClickEvent(aPresContext, NS_STATIC_CAST(nsInputEvent*, aEvent),
content, PR_TRUE, &status);
// Do we care about the status this returned? I don't think we do...
}
break;
case NS_FOCUS_CONTENT:
// Since we don't have '-moz-user-focus: normal', the only time
@ -252,8 +251,12 @@ nsHTMLLabelElement::HandleDOMEvent(nsPresContext* aPresContext,
// case.
// Since focus doesn't bubble, this is basically the second part
// of redirecting |SetFocus|.
rv = content->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
{
nsEvent event(NS_FOCUS_CONTENT);
nsEventStatus status = *aEventStatus;
rv = DispatchEvent(aPresContext, &event, content, PR_TRUE, &status);
// Do we care about the status this returned? I don't think we do...
}
break;
}
mHandlingEvent = PR_FALSE;