mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 20:35:50 +00:00
Set the status bar before actually handling the DOM event. That way if theevent is canceled, we'll still show the right status bar text. Bug 40838,patch by Florian Quèze <f.qu@queze.net, r=smaug, sr=bzbarsky
This commit is contained in:
parent
7e52b169fd
commit
bcfbc64387
@ -49,6 +49,7 @@ class nsIContent;
|
||||
class nsIDocument;
|
||||
class nsIDOMEvent;
|
||||
class nsPresContext;
|
||||
class nsEventChainVisitor;
|
||||
class nsEventChainPreVisitor;
|
||||
class nsEventChainPostVisitor;
|
||||
class nsIEventListenerManager;
|
||||
|
@ -3794,6 +3794,74 @@ nsGenericElement::CreateSlots()
|
||||
return new nsDOMSlots(mFlagsOrSlots);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsGenericElement::CheckHandleEventForLinksPrecondition(nsEventChainVisitor& aVisitor,
|
||||
nsIURI** aURI) const
|
||||
{
|
||||
if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault ||
|
||||
!NS_IS_TRUSTED_EVENT(aVisitor.mEvent) ||
|
||||
!aVisitor.mPresContext) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Make sure we actually are a link
|
||||
return IsLink(aURI);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::PreHandleEventForLinks(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
// Optimisation: return early if this event doesn't interest us.
|
||||
// IMPORTANT: this switch and the switch below it must be kept in sync!
|
||||
switch (aVisitor.mEvent->message) {
|
||||
case NS_MOUSE_ENTER_SYNTH:
|
||||
case NS_FOCUS_CONTENT:
|
||||
case NS_MOUSE_EXIT_SYNTH:
|
||||
case NS_BLUR_CONTENT:
|
||||
break;
|
||||
default:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Make sure we meet the preconditions before continuing
|
||||
nsCOMPtr<nsIURI> absURI;
|
||||
if (!CheckHandleEventForLinksPrecondition(aVisitor, getter_AddRefs(absURI))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// We do the status bar updates in PreHandleEvent so that the status bar gets
|
||||
// updated even if the event is consumed before we have a chance to set it.
|
||||
switch (aVisitor.mEvent->message) {
|
||||
// Set the status bar the same for focus and mouseover
|
||||
case NS_MOUSE_ENTER_SYNTH:
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
// FALL THROUGH
|
||||
case NS_FOCUS_CONTENT:
|
||||
{
|
||||
nsAutoString target;
|
||||
GetLinkTarget(target);
|
||||
rv = TriggerLink(aVisitor.mPresContext, absURI, target, PR_FALSE, PR_TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case NS_MOUSE_EXIT_SYNTH:
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
// FALL THROUGH
|
||||
case NS_BLUR_CONTENT:
|
||||
rv = LeaveLink(aVisitor.mPresContext);
|
||||
break;
|
||||
|
||||
default:
|
||||
// switch not in sync with the optimization switch earlier in this function
|
||||
NS_NOTREACHED("switch statements not in sync");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::PostHandleEventForLinks(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
@ -3804,24 +3872,14 @@ nsGenericElement::PostHandleEventForLinks(nsEventChainPostVisitor& aVisitor)
|
||||
case NS_MOUSE_CLICK:
|
||||
case NS_UI_ACTIVATE:
|
||||
case NS_KEY_PRESS:
|
||||
case NS_MOUSE_ENTER_SYNTH:
|
||||
case NS_FOCUS_CONTENT:
|
||||
case NS_MOUSE_EXIT_SYNTH:
|
||||
case NS_BLUR_CONTENT:
|
||||
break;
|
||||
default:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault ||
|
||||
!NS_IS_TRUSTED_EVENT(aVisitor.mEvent) ||
|
||||
!aVisitor.mPresContext) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Make sure we actually are a link before continuing
|
||||
// Make sure we meet the preconditions before continuing
|
||||
nsCOMPtr<nsIURI> absURI;
|
||||
if (!IsLink(getter_AddRefs(absURI))) {
|
||||
if (!CheckHandleEventForLinksPrecondition(aVisitor, getter_AddRefs(absURI))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3908,27 +3966,6 @@ nsGenericElement::PostHandleEventForLinks(nsEventChainPostVisitor& aVisitor)
|
||||
}
|
||||
break;
|
||||
|
||||
// Set the status bar the same for focus and mouseover
|
||||
case NS_MOUSE_ENTER_SYNTH:
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
// FALL THROUGH
|
||||
case NS_FOCUS_CONTENT:
|
||||
{
|
||||
nsAutoString target;
|
||||
GetLinkTarget(target);
|
||||
rv = TriggerLink(aVisitor.mPresContext, absURI, target, PR_FALSE, PR_TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case NS_MOUSE_EXIT_SYNTH:
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
rv = LeaveLink(aVisitor.mPresContext);
|
||||
break;
|
||||
|
||||
case NS_BLUR_CONTENT:
|
||||
rv = LeaveLink(aVisitor.mPresContext);
|
||||
break;
|
||||
|
||||
default:
|
||||
// switch not in sync with the optimization switch earlier in this function
|
||||
NS_NOTREACHED("switch statements not in sync");
|
||||
|
@ -1005,9 +1005,29 @@ protected:
|
||||
void GetContentsAsText(nsAString& aText);
|
||||
|
||||
/**
|
||||
* Unified function to carry out event default actions for links of all types
|
||||
* Functions to carry out event default actions for links of all types
|
||||
* (HTML links, XLinks, SVG "XLinks", etc.)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check that we meet the conditions to handle a link event
|
||||
* and that we are actually on a link.
|
||||
*
|
||||
* @param aVisitor event visitor
|
||||
* @param aURI the uri of the link, set only if the return value is PR_TRUE [OUT]
|
||||
* @return PR_TRUE if we can handle the link event, PR_FALSE otherwise
|
||||
*/
|
||||
PRBool CheckHandleEventForLinksPrecondition(nsEventChainVisitor& aVisitor,
|
||||
nsIURI** aURI) const;
|
||||
|
||||
/**
|
||||
* Handle status bar updates before they can be cancelled.
|
||||
*/
|
||||
nsresult PreHandleEventForLinks(nsEventChainPreVisitor& aVisitor);
|
||||
|
||||
/**
|
||||
* Handle default actions for link event if the event isn't consumed yet.
|
||||
*/
|
||||
nsresult PostHandleEventForLinks(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
/**
|
||||
|
@ -1255,8 +1255,8 @@ IsArea(nsIContent *aContent)
|
||||
aContent->IsNodeOfType(nsINode::eHTML));
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::PostHandleEventForAnchors(nsEventChainPostVisitor& aVisitor)
|
||||
PRBool
|
||||
nsGenericHTMLElement::CheckHandleEventForAnchorsPreconditions(nsEventChainVisitor& aVisitor)
|
||||
{
|
||||
NS_PRECONDITION(nsCOMPtr<nsILink>(do_QueryInterface(this)),
|
||||
"should be called only when |this| implements |nsILink|");
|
||||
@ -1265,7 +1265,7 @@ nsGenericHTMLElement::PostHandleEventForAnchors(nsEventChainPostVisitor& aVisito
|
||||
// We need a pres context to do link stuff. Some events (e.g. mutation
|
||||
// events) don't have one.
|
||||
// XXX: ideally, shouldn't we be able to do what we need without one?
|
||||
return NS_OK;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
//Need to check if we hit an imagemap area and if so see if we're handling
|
||||
@ -1275,7 +1275,26 @@ nsGenericHTMLElement::PostHandleEventForAnchors(nsEventChainPostVisitor& aVisito
|
||||
aVisitor.mPresContext->EventStateManager()->
|
||||
GetEventTargetContent(aVisitor.mEvent, getter_AddRefs(target));
|
||||
|
||||
if (target && IsArea(target) && !IsArea(this)) {
|
||||
return !target || !IsArea(target) || IsArea(this);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::PreHandleEventForAnchors(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
nsresult rv = nsGenericElement::PreHandleEvent(aVisitor);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!CheckHandleEventForAnchorsPreconditions(aVisitor)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return PreHandleEventForLinks(aVisitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::PostHandleEventForAnchors(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
if (!CheckHandleEventForAnchorsPreconditions(aVisitor)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -202,6 +202,12 @@ public:
|
||||
virtual void PerformAccesskey(PRBool aKeyCausesActivation,
|
||||
PRBool aIsTrustedEvent);
|
||||
|
||||
/**
|
||||
* Check if an event for an anchor can be handled
|
||||
* @return PR_TRUE if the event can be handled, PR_FALSE otherwise
|
||||
*/
|
||||
PRBool CheckHandleEventForAnchorsPreconditions(nsEventChainVisitor& aVisitor);
|
||||
nsresult PreHandleEventForAnchors(nsEventChainPreVisitor& aVisitor);
|
||||
nsresult PostHandleEventForAnchors(nsEventChainPostVisitor& aVisitor);
|
||||
PRBool IsHTMLLink(nsIURI** aURI) const;
|
||||
|
||||
|
@ -111,6 +111,7 @@ public:
|
||||
virtual void SetFocus(nsPresContext* aPresContext);
|
||||
virtual PRBool IsFocusable(PRBool *aTabIndex = nsnull);
|
||||
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual PRBool IsLink(nsIURI** aURI) const;
|
||||
virtual void GetLinkTarget(nsAString& aTarget);
|
||||
@ -275,6 +276,12 @@ nsHTMLAnchorElement::IsFocusable(PRInt32 *aTabIndex)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLAnchorElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
return PreHandleEventForAnchors(aVisitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLAnchorElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
|
@ -87,6 +87,7 @@ public:
|
||||
NS_IMETHOD LinkAdded() { return NS_OK; }
|
||||
NS_IMETHOD LinkRemoved() { return NS_OK; }
|
||||
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual PRBool IsLink(nsIURI** aURI) const;
|
||||
virtual void GetLinkTarget(nsAString& aTarget);
|
||||
@ -170,6 +171,12 @@ nsHTMLAreaElement::SetTarget(const nsAString& aValue)
|
||||
return SetAttr(kNameSpaceID_None, nsGkAtoms::target, aValue, PR_TRUE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLAreaElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
return PreHandleEventForAnchors(aVisitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLAreaElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
|
@ -107,6 +107,7 @@ public:
|
||||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify);
|
||||
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual PRBool IsLink(nsIURI** aURI) const;
|
||||
virtual void GetLinkTarget(nsAString& aTarget);
|
||||
@ -325,6 +326,12 @@ nsHTMLLinkElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLLinkElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
return PreHandleEventForAnchors(aVisitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLLinkElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
|
@ -69,6 +69,7 @@ public:
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGAElementBase::)
|
||||
|
||||
// nsINode interface methods
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
@ -168,6 +169,15 @@ nsSVGAElement::GetHref(nsIDOMSVGAnimatedString * *aHref)
|
||||
//----------------------------------------------------------------------
|
||||
// nsINode methods
|
||||
|
||||
nsresult
|
||||
nsSVGAElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
nsresult rv = nsGenericElement::PreHandleEvent(aVisitor);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return PreHandleEventForLinks(aVisitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGAElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
|
@ -113,6 +113,15 @@ DocShellToPresContext(nsIDocShell *aShell, nsPresContext **aPresContext)
|
||||
return ds->GetPresContext(aPresContext);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXMLElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
nsresult rv = nsGenericElement::PreHandleEvent(aVisitor);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return PreHandleEventForLinks(aVisitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXMLElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
|
@ -60,6 +60,7 @@ public:
|
||||
NS_FORWARD_NSIDOMELEMENT(nsGenericElement::)
|
||||
|
||||
// nsINode interface methods
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user