diff --git a/content/html/content/reftests/href-attr-removal-restyles-ref.html b/content/html/content/reftests/href-attr-removal-restyles-ref.html new file mode 100644 index 000000000000..958f5da2bb0a --- /dev/null +++ b/content/html/content/reftests/href-attr-removal-restyles-ref.html @@ -0,0 +1,20 @@ + + + + Test for bug 549797 - Removing href attribute doesn't remove link styling + + + +

+ Test anchor + +

+ + diff --git a/content/html/content/reftests/href-attr-removal-restyles.html b/content/html/content/reftests/href-attr-removal-restyles.html new file mode 100644 index 000000000000..4eecbd4e9466 --- /dev/null +++ b/content/html/content/reftests/href-attr-removal-restyles.html @@ -0,0 +1,29 @@ + + + + Test for bug 549797 - Removing href attribute doesn't remove link styling + + + + +

+ Test anchor + +

+ + diff --git a/content/html/content/reftests/reftest.list b/content/html/content/reftests/reftest.list index 163d3fe9daa0..ec2c73a0ab72 100644 --- a/content/html/content/reftests/reftest.list +++ b/content/html/content/reftests/reftest.list @@ -7,3 +7,4 @@ == 468263-2.html 468263-2-ref.html == 468263-2.html 468263-2-alternate-ref.html == 484200-1.html 484200-1-ref.html +== href-attr-removal-restyles.html href-attr-removal-restyles-ref.html diff --git a/content/html/content/src/nsHTMLAnchorElement.cpp b/content/html/content/src/nsHTMLAnchorElement.cpp index 10c69ee42bd7..8fbe7669b802 100644 --- a/content/html/content/src/nsHTMLAnchorElement.cpp +++ b/content/html/content/src/nsHTMLAnchorElement.cpp @@ -468,16 +468,24 @@ nsresult nsHTMLAnchorElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRBool aNotify) { - if (aAttribute == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) { - Link::ResetLinkState(!!aNotify); - } - if (aAttribute == nsGkAtoms::accesskey && kNameSpaceID_None == aNameSpaceID) { RegUnRegAccessKey(PR_FALSE); } - return nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify); + nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute, + aNotify); + + // The ordering of the parent class's UnsetAttr call and Link::ResetLinkState + // is important here! The attribute is not unset until UnsetAttr 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 (aAttribute == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) { + Link::ResetLinkState(!!aNotify); + } + + return rv; } PRBool diff --git a/content/html/content/src/nsHTMLAreaElement.cpp b/content/html/content/src/nsHTMLAreaElement.cpp index e763810c703b..c7a69e94bc28 100644 --- a/content/html/content/src/nsHTMLAreaElement.cpp +++ b/content/html/content/src/nsHTMLAreaElement.cpp @@ -267,16 +267,24 @@ nsresult nsHTMLAreaElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRBool aNotify) { - if (aAttribute == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) { - Link::ResetLinkState(!!aNotify); - } - if (aAttribute == nsGkAtoms::accesskey && aNameSpaceID == kNameSpaceID_None) { RegUnRegAccessKey(PR_FALSE); } - return nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify); + nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute, + aNotify); + + // The ordering of the parent class's UnsetAttr call and Link::ResetLinkState + // is important here! The attribute is not unset until UnsetAttr 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 (aAttribute == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) { + Link::ResetLinkState(!!aNotify); + } + + return rv; } #define IMPL_URI_PART(_part) \ diff --git a/content/html/content/src/nsHTMLLinkElement.cpp b/content/html/content/src/nsHTMLLinkElement.cpp index 095c2c2718f7..0aeb6212ece1 100644 --- a/content/html/content/src/nsHTMLLinkElement.cpp +++ b/content/html/content/src/nsHTMLLinkElement.cpp @@ -322,10 +322,6 @@ nsresult nsHTMLLinkElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRBool aNotify) { - if (aAttribute == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) { - Link::ResetLinkState(!!aNotify); - } - nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify); if (NS_SUCCEEDED(rv)) { @@ -337,6 +333,15 @@ nsHTMLLinkElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute, aAttribute == nsGkAtoms::type)); } + // The ordering of the parent class's UnsetAttr call and Link::ResetLinkState + // is important here! The attribute is not unset until UnsetAttr 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 (aAttribute == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) { + Link::ResetLinkState(!!aNotify); + } + return rv; } diff --git a/content/svg/content/src/nsSVGAElement.cpp b/content/svg/content/src/nsSVGAElement.cpp index 37a768ed1a63..bf37574e7579 100644 --- a/content/svg/content/src/nsSVGAElement.cpp +++ b/content/svg/content/src/nsSVGAElement.cpp @@ -286,11 +286,18 @@ nsresult nsSVGAElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttr, PRBool aNotify) { + nsresult rv = nsSVGAElementBase::UnsetAttr(aNameSpaceID, aAttr, aNotify); + + // The ordering of the parent class's UnsetAttr call and Link::ResetLinkState + // is important here! The attribute is not unset until UnsetAttr 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 (aAttr == nsGkAtoms::href && aNameSpaceID == kNameSpaceID_XLink) { Link::ResetLinkState(!!aNotify); } - return nsSVGAElementBase::UnsetAttr(aNameSpaceID, aAttr, aNotify); + return rv; } //---------------------------------------------------------------------- diff --git a/layout/reftests/svg/href-attr-removal-restyles-ref.svg b/layout/reftests/svg/href-attr-removal-restyles-ref.svg new file mode 100644 index 000000000000..32c2b7370486 --- /dev/null +++ b/layout/reftests/svg/href-attr-removal-restyles-ref.svg @@ -0,0 +1,21 @@ + + + Test for bug 549797 - Removing href attribute doesn't remove link styling + + + + + Test anchor + + + diff --git a/layout/reftests/svg/href-attr-removal-restyles.svg b/layout/reftests/svg/href-attr-removal-restyles.svg new file mode 100644 index 000000000000..44189373e00b --- /dev/null +++ b/layout/reftests/svg/href-attr-removal-restyles.svg @@ -0,0 +1,22 @@ + + + Test for bug 549797 - Removing href attribute doesn't remove link styling + + + + + Test anchor + + + diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list index 67a5241d0936..90f98333b88e 100644 --- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -154,3 +154,4 @@ random-if(MOZ_WIDGET_TOOLKIT=="gtk2") != text-language-01.xhtml text-language-01 == svg-effects-area-unzoomed.xhtml svg-effects-area-unzoomed-ref.xhtml fails == svg-effects-area-zoomed-in.xhtml svg-effects-area-zoomed-in-ref.xhtml # Bug 541270 fails == svg-effects-area-zoomed-out.xhtml svg-effects-area-zoomed-out-ref.xhtml # Bug 541270 +== href-attr-removal-restyles.svg href-attr-removal-restyles-ref.svg