Bug 461199 (Part 30) - Fixes invalidation issues when changing the href attribute.

r=bz
This commit is contained in:
Shawn Wilsher 2010-02-17 14:04:34 -08:00
parent 5af603aed6
commit 6ab4a07558
5 changed files with 39 additions and 16 deletions

View File

@ -60,7 +60,7 @@ public:
static const nsLinkState defaultState = eLinkState_Unknown; static const nsLinkState defaultState = eLinkState_Unknown;
Link(); Link();
virtual nsLinkState GetLinkState() const; nsLinkState GetLinkState() const;
virtual void SetLinkState(nsLinkState aState); virtual void SetLinkState(nsLinkState aState);
/** /**
@ -100,7 +100,7 @@ public:
* true if ResetLinkState should notify the owning document about style * true if ResetLinkState should notify the owning document about style
* changes or false if it should not. * changes or false if it should not.
*/ */
virtual void ResetLinkState(bool aNotify); void ResetLinkState(bool aNotify);
protected: protected:
virtual ~Link(); virtual ~Link();

View File

@ -431,6 +431,18 @@ nsHTMLAnchorElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue, nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify) PRBool aNotify)
{ {
if (aName == nsGkAtoms::accesskey && kNameSpaceID_None == aNameSpaceID) {
RegUnRegAccessKey(PR_FALSE);
}
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
aValue, aNotify);
// The ordering of the parent class's SetAttr call and Link::ResetLinkState
// is important here! The attribute is not set until SetAttr returns, and
// we will need the updated attribute value because notifying the document
// that content states have changed will call IntrinsicState, which will try
// to get updated information about the visitedness from Link.
if (aName == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) { if (aName == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) {
nsAutoString val; nsAutoString val;
GetHref(val); GetHref(val);
@ -439,13 +451,6 @@ nsHTMLAnchorElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
} }
} }
if (aName == nsGkAtoms::accesskey && kNameSpaceID_None == aNameSpaceID) {
RegUnRegAccessKey(PR_FALSE);
}
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
aValue, aNotify);
if (aName == nsGkAtoms::accesskey && kNameSpaceID_None == aNameSpaceID && if (aName == nsGkAtoms::accesskey && kNameSpaceID_None == aNameSpaceID &&
!aValue.IsEmpty()) { !aValue.IsEmpty()) {
RegUnRegAccessKey(PR_TRUE); RegUnRegAccessKey(PR_TRUE);

View File

@ -243,13 +243,18 @@ nsHTMLAreaElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
RegUnRegAccessKey(PR_FALSE); RegUnRegAccessKey(PR_FALSE);
} }
nsresult rv =
nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue, aNotify);
// The ordering of the parent class's SetAttr call and Link::ResetLinkState
// is important here! The attribute is not set until SetAttr returns, and
// we will need the updated attribute value because notifying the document
// that content states have changed will call IntrinsicState, which will try
// to get updated information about the visitedness from Link.
if (aName == nsGkAtoms::href && aNameSpaceID == kNameSpaceID_None) { if (aName == nsGkAtoms::href && aNameSpaceID == kNameSpaceID_None) {
Link::ResetLinkState(!!aNotify); Link::ResetLinkState(!!aNotify);
} }
nsresult rv =
nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue, aNotify);
if (aName == nsGkAtoms::accesskey && aNameSpaceID == kNameSpaceID_None && if (aName == nsGkAtoms::accesskey && aNameSpaceID == kNameSpaceID_None &&
!aValue.IsEmpty()) { !aValue.IsEmpty()) {
RegUnRegAccessKey(PR_TRUE); RegUnRegAccessKey(PR_TRUE);

View File

@ -285,12 +285,18 @@ nsHTMLLinkElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue, nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify) PRBool aNotify)
{ {
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
aValue, aNotify);
// The ordering of the parent class's SetAttr call and Link::ResetLinkState
// is important here! The attribute is not set until SetAttr returns, and
// we will need the updated attribute value because notifying the document
// that content states have changed will call IntrinsicState, which will try
// to get updated information about the visitedness from Link.
if (aName == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) { if (aName == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) {
Link::ResetLinkState(!!aNotify); Link::ResetLinkState(!!aNotify);
} }
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
aValue, aNotify);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
PRBool dropSheet = PR_FALSE; PRBool dropSheet = PR_FALSE;
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::rel && if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::rel &&

View File

@ -267,12 +267,19 @@ nsSVGAElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue, nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify) PRBool aNotify)
{ {
nsresult rv = nsSVGAElementBase::SetAttr(aNameSpaceID, aName, aPrefix,
aValue, aNotify);
// The ordering of the parent class's SetAttr call and Link::ResetLinkState
// is important here! The attribute is not set until SetAttr returns, and
// we will need the updated attribute value because notifying the document
// that content states have changed will call IntrinsicState, which will try
// to get updated information about the visitedness from Link.
if (aName == nsGkAtoms::href && aNameSpaceID == kNameSpaceID_XLink) { if (aName == nsGkAtoms::href && aNameSpaceID == kNameSpaceID_XLink) {
Link::ResetLinkState(!!aNotify); Link::ResetLinkState(!!aNotify);
} }
return nsSVGAElementBase::SetAttr(aNameSpaceID, aName, aPrefix, aValue, return rv;
aNotify);
} }
nsresult nsresult