From 19a9279a84ac66609d3a7cc884eaee246530cf3e Mon Sep 17 00:00:00 2001 From: "dbaron%dbaron.org" Date: Mon, 13 Jan 2003 23:10:53 +0000 Subject: [PATCH] Implement CSS3 :target pseudo-class, which matches the target of the fragment identifier of the document's URL. Change the semantics of nsIPresShell::GoToAnchor by requiring that it be called whenever the current target changes, with an additional boolean parameter specifying whether to scroll. b=188734 r=glazman sr=bzbarsky git-svn-id: svn://10.0.0.236/trunk@136266 18797224-902f-48f8-a5cc-f745e15eee43 --- .../events/public/nsIEventStateManager.h | 3 +- .../events/src/nsEventStateManager.cpp | 11 ++++- .../content/events/src/nsEventStateManager.h | 1 + .../html/document/src/nsHTMLContentSink.cpp | 4 +- .../html/style/src/nsCSSStyleSheet.cpp | 18 ++++--- .../shared/public/nsCSSPseudoClassList.h | 1 + .../xml/document/src/nsXMLContentSink.cpp | 4 +- mozilla/docshell/base/nsDocShell.cpp | 20 +++++--- mozilla/layout/base/nsIPresShell.h | 10 ++-- mozilla/layout/base/nsPresShell.cpp | 49 +++++++++++++------ mozilla/layout/base/public/nsIPresShell.h | 10 ++-- mozilla/layout/html/base/src/nsPresShell.cpp | 49 +++++++++++++------ mozilla/layout/style/nsCSSPseudoClassList.h | 1 + mozilla/layout/style/nsCSSStyleSheet.cpp | 18 ++++--- 14 files changed, 136 insertions(+), 63 deletions(-) diff --git a/mozilla/content/events/public/nsIEventStateManager.h b/mozilla/content/events/public/nsIEventStateManager.h index ebf74ec9b14..d362564f57e 100644 --- a/mozilla/content/events/public/nsIEventStateManager.h +++ b/mozilla/content/events/public/nsIEventStateManager.h @@ -123,8 +123,9 @@ public: #define NS_EVENT_STATE_FOCUS 0x0002 // content has focus #define NS_EVENT_STATE_HOVER 0x0004 // mouse is hovering over content #define NS_EVENT_STATE_DRAGOVER 0x0008 // drag is hovering over content +#define NS_EVENT_STATE_URLTARGET 0x0010 // content is URL's target (ref) // The following states are used only for ContentStatesChanged -#define NS_EVENT_STATE_CHECKED 0x0010 +#define NS_EVENT_STATE_CHECKED 0x0020 enum EFocusedWithType { eEventFocusedByUnknown, // focus gained via unknown method diff --git a/mozilla/content/events/src/nsEventStateManager.cpp b/mozilla/content/events/src/nsEventStateManager.cpp index 15681b75910..1c2f9db964e 100644 --- a/mozilla/content/events/src/nsEventStateManager.cpp +++ b/mozilla/content/events/src/nsEventStateManager.cpp @@ -3803,13 +3803,16 @@ nsEventStateManager::GetContentState(nsIContent *aContent, PRInt32& aState) if (aContent == mDragOverContent) { aState |= NS_EVENT_STATE_DRAGOVER; } + if (aContent == mURLTargetContent) { + aState |= NS_EVENT_STATE_URLTARGET; + } return NS_OK; } NS_IMETHODIMP nsEventStateManager::SetContentState(nsIContent *aContent, PRInt32 aState) { - const PRInt32 maxNotify = 5; + const PRInt32 maxNotify = 6; // We must initialize this array with memset for the sake of the boneheaded // OS X compiler. See bug 134934. nsIContent *notifyContent[maxNotify]; @@ -3831,6 +3834,12 @@ nsEventStateManager::SetContentState(nsIContent *aContent, PRInt32 aState) mDragOverContent = aContent; } + if ((aState & NS_EVENT_STATE_URLTARGET) && (aContent != mURLTargetContent)) { + notifyContent[5] = mURLTargetContent; + NS_IF_ADDREF(notifyContent[5]); + mURLTargetContent = aContent; + } + if ((aState & NS_EVENT_STATE_ACTIVE) && (aContent != mActiveContent)) { //transferring ref to notifyContent from mActiveContent notifyContent[2] = mActiveContent; diff --git a/mozilla/content/events/src/nsEventStateManager.h b/mozilla/content/events/src/nsEventStateManager.h index fb74a4313c5..f3c63c770e9 100644 --- a/mozilla/content/events/src/nsEventStateManager.h +++ b/mozilla/content/events/src/nsEventStateManager.h @@ -257,6 +257,7 @@ protected: nsCOMPtr mActiveContent; nsCOMPtr mHoverContent; nsCOMPtr mDragOverContent; + nsCOMPtr mURLTargetContent; nsCOMPtr mCurrentFocus; PRInt32 mLastFocusedWith; PRInt32 mCurrentTabIndex; diff --git a/mozilla/content/html/document/src/nsHTMLContentSink.cpp b/mozilla/content/html/document/src/nsHTMLContentSink.cpp index c517f4c9590..d373d34b610 100644 --- a/mozilla/content/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/content/html/document/src/nsHTMLContentSink.cpp @@ -4346,7 +4346,7 @@ HTMLContentSink::ScrollToRef() // Check an empty string which might be caused by the UTF-8 conversion if (!ref.IsEmpty()) { - rv = shell->GoToAnchor(ref); + rv = shell->GoToAnchor(ref, PR_TRUE); } else { rv = NS_ERROR_FAILURE; } @@ -4362,7 +4362,7 @@ HTMLContentSink::ScrollToRef() rv = CharsetConvRef(docCharset, unescapedRef, ref); if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) - rv = shell->GoToAnchor(ref); + rv = shell->GoToAnchor(ref, PR_TRUE); } } diff --git a/mozilla/content/html/style/src/nsCSSStyleSheet.cpp b/mozilla/content/html/style/src/nsCSSStyleSheet.cpp index e82dd804f39..4b297816a88 100644 --- a/mozilla/content/html/style/src/nsCSSStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsCSSStyleSheet.cpp @@ -3554,11 +3554,12 @@ static PRBool ValueIncludes(const nsString& aValueList, const nsString& aValue, inline PRBool IsEventPseudo(nsIAtom* aAtom) { - return PRBool ((nsCSSPseudoClasses::active == aAtom) || - (nsCSSPseudoClasses::mozDragOver == aAtom) || - (nsCSSPseudoClasses::focus == aAtom) || - (nsCSSPseudoClasses::hover == aAtom)); - // XXX selected, enabled, disabled, selection? + return nsCSSPseudoClasses::active == aAtom || + nsCSSPseudoClasses::mozDragOver == aAtom || + nsCSSPseudoClasses::focus == aAtom || + nsCSSPseudoClasses::hover == aAtom || + nsCSSPseudoClasses::target == aAtom; + // XXX selected, enabled, disabled, selection? } inline PRBool IsLinkPseudo(nsIAtom* aAtom) @@ -3844,6 +3845,10 @@ static PRBool SelectorMatches(RuleProcessorData &data, result = (aStateMask & NS_EVENT_STATE_DRAGOVER) || (localTrue == (0 != (data.mEventState & NS_EVENT_STATE_DRAGOVER))); } + else if (nsCSSPseudoClasses::target == pseudoClass->mAtom) { + result = (aStateMask & NS_EVENT_STATE_URLTARGET) || + (localTrue == (0 != (data.mEventState & NS_EVENT_STATE_URLTARGET))); + } } } else if (IsLinkPseudo(pseudoClass->mAtom)) { @@ -4443,7 +4448,8 @@ PRBool IsStateSelector(nsCSSSelector& aSelector) (pseudoClass->mAtom == nsCSSPseudoClasses::checked) || (pseudoClass->mAtom == nsCSSPseudoClasses::mozDragOver) || (pseudoClass->mAtom == nsCSSPseudoClasses::focus) || - (pseudoClass->mAtom == nsCSSPseudoClasses::hover)) { + (pseudoClass->mAtom == nsCSSPseudoClasses::hover) || + (pseudoClass->mAtom == nsCSSPseudoClasses::target)) { return PR_TRUE; } pseudoClass = pseudoClass->mNext; diff --git a/mozilla/content/shared/public/nsCSSPseudoClassList.h b/mozilla/content/shared/public/nsCSSPseudoClassList.h index 7569596ca80..28b05fe1e7a 100644 --- a/mozilla/content/shared/public/nsCSSPseudoClassList.h +++ b/mozilla/content/shared/public/nsCSSPseudoClassList.h @@ -64,6 +64,7 @@ CSS_PSEUDO_CLASS(enabled, ":enabled") CSS_PSEUDO_CLASS(focus, ":focus") CSS_PSEUDO_CLASS(hover, ":hover") CSS_PSEUDO_CLASS(mozDragOver, ":-moz-drag-over") +CSS_PSEUDO_CLASS(target, ":target") CSS_PSEUDO_CLASS(firstChild, ":first-child") CSS_PSEUDO_CLASS(firstNode, ":first-node") diff --git a/mozilla/content/xml/document/src/nsXMLContentSink.cpp b/mozilla/content/xml/document/src/nsXMLContentSink.cpp index 1f1cce41b86..b345f865631 100644 --- a/mozilla/content/xml/document/src/nsXMLContentSink.cpp +++ b/mozilla/content/xml/document/src/nsXMLContentSink.cpp @@ -297,7 +297,7 @@ nsXMLContentSink::ScrollToRef() // Check an empty string which might be caused by the UTF-8 conversion if (!ref.IsEmpty()) - rv = shell->GoToAnchor(ref); + rv = shell->GoToAnchor(ref, PR_TRUE); else rv = NS_ERROR_FAILURE; @@ -312,7 +312,7 @@ nsXMLContentSink::ScrollToRef() rv = CharsetConvRef(docCharset, unescapedRef, ref); if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) - rv = shell->GoToAnchor(ref); + rv = shell->GoToAnchor(ref, PR_TRUE); } } } diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp index 72b989c2092..f2943ba7b37 100644 --- a/mozilla/docshell/base/nsDocShell.cpp +++ b/mozilla/docshell/base/nsDocShell.cpp @@ -5649,16 +5649,19 @@ nsDocShell::ScrollIfAnchor(nsIURI * aURI, PRBool * aWasAnchor, PRUint32 aLoadTyp GetCurScrollPos(ScrollOrientation_X, cx); GetCurScrollPos(ScrollOrientation_Y, cy); + nsCOMPtr shell; + rv = GetPresShell(getter_AddRefs(shell)); + if (NS_FAILED(rv)) + return rv; + if (!sNewRef.IsEmpty()) { - nsCOMPtr shell = nsnull; - rv = GetPresShell(getter_AddRefs(shell)); - if (NS_SUCCEEDED(rv) && shell) { + if (shell) { *aWasAnchor = PR_TRUE; // anchor is there, but if it's a load from history, // we don't have any anchor jumping to do - if (aLoadType == LOAD_HISTORY || aLoadType == LOAD_RELOAD_NORMAL) - return rv; + PRBool scroll = aLoadType != LOAD_HISTORY && + aLoadType != LOAD_RELOAD_NORMAL; char *str = ToNewCString(sNewRef); @@ -5670,7 +5673,7 @@ nsDocShell::ScrollIfAnchor(nsIURI * aURI, PRBool * aWasAnchor, PRUint32 aLoadTyp // We try the UTF-8 string first, and then try the // document's charset (see below). - rv = shell->GoToAnchor(NS_ConvertUTF8toUCS2(str)); + rv = shell->GoToAnchor(NS_ConvertUTF8toUCS2(str), scroll); nsMemory::Free(str); // Above will fail if the anchor name is not UTF-8. @@ -5703,12 +5706,15 @@ nsDocShell::ScrollIfAnchor(nsIURI * aURI, PRBool * aWasAnchor, PRUint32 aLoadTyp getter_Copies(uStr)); NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); - rv = shell->GoToAnchor(uStr); + rv = shell->GoToAnchor(uStr, scroll); } } } else { *aWasAnchor = PR_TRUE; + + // Tell the shell it's at an anchor, without scrolling. + shell->GoToAnchor(NS_LITERAL_STRING(""), PR_FALSE); // An empty anchor was found, but if it's a load from history, // we don't have to jump to the top of the page. Scrollbar diff --git a/mozilla/layout/base/nsIPresShell.h b/mozilla/layout/base/nsIPresShell.h index 38a42a041be..a99e6957834 100644 --- a/mozilla/layout/base/nsIPresShell.h +++ b/mozilla/layout/base/nsIPresShell.h @@ -352,10 +352,14 @@ public: /** - * Scrolls the view of the document so that the anchor with the specified - * name is displayed at the top of the window + * Informs the pres shell that the document is now at the anchor with + * the given name. If |aScroll| is true, scrolls the view of the + * document so that the anchor with the specified name is displayed at + * the top of the window. If |aAnchorName| is empty, then this informs + * the pres shell that there is no current target, and |aScroll| must + * be false. */ - NS_IMETHOD GoToAnchor(const nsAString& aAnchorName) = 0; + NS_IMETHOD GoToAnchor(const nsAString& aAnchorName, PRBool aScroll) = 0; /** * Scrolls the view of the document so that the frame is displayed at the diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index 9e1dd4092d2..3e88f59826e 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -1105,7 +1105,7 @@ public: nsIRenderingContext** aContext); NS_IMETHOD CantRenderReplacedElement(nsIPresContext* aPresContext, nsIFrame* aFrame); - NS_IMETHOD GoToAnchor(const nsAString& aAnchorName); + NS_IMETHOD GoToAnchor(const nsAString& aAnchorName, PRBool aScroll); NS_IMETHOD ScrollFrameIntoView(nsIFrame *aFrame, PRIntn aVPercent, @@ -3930,8 +3930,18 @@ PresShell::CantRenderReplacedElement(nsIPresContext* aPresContext, } NS_IMETHODIMP -PresShell::GoToAnchor(const nsAString& aAnchorName) +PresShell::GoToAnchor(const nsAString& aAnchorName, PRBool aScroll) { + nsCOMPtr esm; + mPresContext->GetEventStateManager(getter_AddRefs(esm)); + if (aAnchorName.IsEmpty()) { + NS_ASSERTION(!aScroll, "can't scroll to empty anchor name"); + if (esm) { + esm->SetContentState(nsnull, NS_EVENT_STATE_URLTARGET); + } + return NS_OK; + } + nsCOMPtr doc = do_QueryInterface(mDocument); nsCOMPtr htmlDoc = do_QueryInterface(mDocument); nsresult rv = NS_OK; @@ -4025,11 +4035,16 @@ PresShell::GoToAnchor(const nsAString& aAnchorName) } } - if (content) { - nsIFrame* frame = nsnull; + if (esm) { + esm->SetContentState(content, NS_EVENT_STATE_URLTARGET); + } + if (content) { // Get the primary frame - if (NS_SUCCEEDED(GetPrimaryFrameFor(content, &frame)) && frame) { + nsIFrame* frame = nsnull; + if (aScroll && + NS_SUCCEEDED(GetPrimaryFrameFor(content, &frame)) && + frame) { rv = ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_TOP, NS_PRESSHELL_SCROLL_ANYWHERE); @@ -4055,8 +4070,7 @@ PresShell::GoToAnchor(const nsAString& aAnchorName) SelectRange(jumpToRange); } - nsCOMPtr esm; - if (NS_SUCCEEDED(mPresContext->GetEventStateManager(getter_AddRefs(esm))) && esm) { + if (esm) { PRBool isSelectionWithFocus; esm->MoveFocusToCaret(PR_TRUE, &isSelectionWithFocus); } @@ -4071,15 +4085,18 @@ PresShell::GoToAnchor(const nsAString& aAnchorName) mPresContext->GetCompatibilityMode(&compatMode); if ((NS_LossyConvertUCS2toASCII(aAnchorName).EqualsIgnoreCase("top")) && - (compatMode == eCompatibility_NavQuirks) && - (mViewManager)) { - // Get the viewport scroller - nsIScrollableView* scrollingView; - mViewManager->GetRootScrollableView(&scrollingView); - if (scrollingView) { - // Scroll to the top of the page - scrollingView->ScrollTo(0, 0, NS_VMREFRESH_IMMEDIATE); - rv = NS_OK; + (compatMode == eCompatibility_NavQuirks)) { + rv = NS_OK; + // Check |aScroll| after setting |rv| so we set |rv| to the same + // thing whether or not |aScroll| is true. + if (aScroll && mViewManager) { + // Get the viewport scroller + nsIScrollableView* scrollingView; + mViewManager->GetRootScrollableView(&scrollingView); + if (scrollingView) { + // Scroll to the top of the page + scrollingView->ScrollTo(0, 0, NS_VMREFRESH_IMMEDIATE); + } } } } diff --git a/mozilla/layout/base/public/nsIPresShell.h b/mozilla/layout/base/public/nsIPresShell.h index 38a42a041be..a99e6957834 100644 --- a/mozilla/layout/base/public/nsIPresShell.h +++ b/mozilla/layout/base/public/nsIPresShell.h @@ -352,10 +352,14 @@ public: /** - * Scrolls the view of the document so that the anchor with the specified - * name is displayed at the top of the window + * Informs the pres shell that the document is now at the anchor with + * the given name. If |aScroll| is true, scrolls the view of the + * document so that the anchor with the specified name is displayed at + * the top of the window. If |aAnchorName| is empty, then this informs + * the pres shell that there is no current target, and |aScroll| must + * be false. */ - NS_IMETHOD GoToAnchor(const nsAString& aAnchorName) = 0; + NS_IMETHOD GoToAnchor(const nsAString& aAnchorName, PRBool aScroll) = 0; /** * Scrolls the view of the document so that the frame is displayed at the diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index 9e1dd4092d2..3e88f59826e 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -1105,7 +1105,7 @@ public: nsIRenderingContext** aContext); NS_IMETHOD CantRenderReplacedElement(nsIPresContext* aPresContext, nsIFrame* aFrame); - NS_IMETHOD GoToAnchor(const nsAString& aAnchorName); + NS_IMETHOD GoToAnchor(const nsAString& aAnchorName, PRBool aScroll); NS_IMETHOD ScrollFrameIntoView(nsIFrame *aFrame, PRIntn aVPercent, @@ -3930,8 +3930,18 @@ PresShell::CantRenderReplacedElement(nsIPresContext* aPresContext, } NS_IMETHODIMP -PresShell::GoToAnchor(const nsAString& aAnchorName) +PresShell::GoToAnchor(const nsAString& aAnchorName, PRBool aScroll) { + nsCOMPtr esm; + mPresContext->GetEventStateManager(getter_AddRefs(esm)); + if (aAnchorName.IsEmpty()) { + NS_ASSERTION(!aScroll, "can't scroll to empty anchor name"); + if (esm) { + esm->SetContentState(nsnull, NS_EVENT_STATE_URLTARGET); + } + return NS_OK; + } + nsCOMPtr doc = do_QueryInterface(mDocument); nsCOMPtr htmlDoc = do_QueryInterface(mDocument); nsresult rv = NS_OK; @@ -4025,11 +4035,16 @@ PresShell::GoToAnchor(const nsAString& aAnchorName) } } - if (content) { - nsIFrame* frame = nsnull; + if (esm) { + esm->SetContentState(content, NS_EVENT_STATE_URLTARGET); + } + if (content) { // Get the primary frame - if (NS_SUCCEEDED(GetPrimaryFrameFor(content, &frame)) && frame) { + nsIFrame* frame = nsnull; + if (aScroll && + NS_SUCCEEDED(GetPrimaryFrameFor(content, &frame)) && + frame) { rv = ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_TOP, NS_PRESSHELL_SCROLL_ANYWHERE); @@ -4055,8 +4070,7 @@ PresShell::GoToAnchor(const nsAString& aAnchorName) SelectRange(jumpToRange); } - nsCOMPtr esm; - if (NS_SUCCEEDED(mPresContext->GetEventStateManager(getter_AddRefs(esm))) && esm) { + if (esm) { PRBool isSelectionWithFocus; esm->MoveFocusToCaret(PR_TRUE, &isSelectionWithFocus); } @@ -4071,15 +4085,18 @@ PresShell::GoToAnchor(const nsAString& aAnchorName) mPresContext->GetCompatibilityMode(&compatMode); if ((NS_LossyConvertUCS2toASCII(aAnchorName).EqualsIgnoreCase("top")) && - (compatMode == eCompatibility_NavQuirks) && - (mViewManager)) { - // Get the viewport scroller - nsIScrollableView* scrollingView; - mViewManager->GetRootScrollableView(&scrollingView); - if (scrollingView) { - // Scroll to the top of the page - scrollingView->ScrollTo(0, 0, NS_VMREFRESH_IMMEDIATE); - rv = NS_OK; + (compatMode == eCompatibility_NavQuirks)) { + rv = NS_OK; + // Check |aScroll| after setting |rv| so we set |rv| to the same + // thing whether or not |aScroll| is true. + if (aScroll && mViewManager) { + // Get the viewport scroller + nsIScrollableView* scrollingView; + mViewManager->GetRootScrollableView(&scrollingView); + if (scrollingView) { + // Scroll to the top of the page + scrollingView->ScrollTo(0, 0, NS_VMREFRESH_IMMEDIATE); + } } } } diff --git a/mozilla/layout/style/nsCSSPseudoClassList.h b/mozilla/layout/style/nsCSSPseudoClassList.h index 7569596ca80..28b05fe1e7a 100644 --- a/mozilla/layout/style/nsCSSPseudoClassList.h +++ b/mozilla/layout/style/nsCSSPseudoClassList.h @@ -64,6 +64,7 @@ CSS_PSEUDO_CLASS(enabled, ":enabled") CSS_PSEUDO_CLASS(focus, ":focus") CSS_PSEUDO_CLASS(hover, ":hover") CSS_PSEUDO_CLASS(mozDragOver, ":-moz-drag-over") +CSS_PSEUDO_CLASS(target, ":target") CSS_PSEUDO_CLASS(firstChild, ":first-child") CSS_PSEUDO_CLASS(firstNode, ":first-node") diff --git a/mozilla/layout/style/nsCSSStyleSheet.cpp b/mozilla/layout/style/nsCSSStyleSheet.cpp index e82dd804f39..4b297816a88 100644 --- a/mozilla/layout/style/nsCSSStyleSheet.cpp +++ b/mozilla/layout/style/nsCSSStyleSheet.cpp @@ -3554,11 +3554,12 @@ static PRBool ValueIncludes(const nsString& aValueList, const nsString& aValue, inline PRBool IsEventPseudo(nsIAtom* aAtom) { - return PRBool ((nsCSSPseudoClasses::active == aAtom) || - (nsCSSPseudoClasses::mozDragOver == aAtom) || - (nsCSSPseudoClasses::focus == aAtom) || - (nsCSSPseudoClasses::hover == aAtom)); - // XXX selected, enabled, disabled, selection? + return nsCSSPseudoClasses::active == aAtom || + nsCSSPseudoClasses::mozDragOver == aAtom || + nsCSSPseudoClasses::focus == aAtom || + nsCSSPseudoClasses::hover == aAtom || + nsCSSPseudoClasses::target == aAtom; + // XXX selected, enabled, disabled, selection? } inline PRBool IsLinkPseudo(nsIAtom* aAtom) @@ -3844,6 +3845,10 @@ static PRBool SelectorMatches(RuleProcessorData &data, result = (aStateMask & NS_EVENT_STATE_DRAGOVER) || (localTrue == (0 != (data.mEventState & NS_EVENT_STATE_DRAGOVER))); } + else if (nsCSSPseudoClasses::target == pseudoClass->mAtom) { + result = (aStateMask & NS_EVENT_STATE_URLTARGET) || + (localTrue == (0 != (data.mEventState & NS_EVENT_STATE_URLTARGET))); + } } } else if (IsLinkPseudo(pseudoClass->mAtom)) { @@ -4443,7 +4448,8 @@ PRBool IsStateSelector(nsCSSSelector& aSelector) (pseudoClass->mAtom == nsCSSPseudoClasses::checked) || (pseudoClass->mAtom == nsCSSPseudoClasses::mozDragOver) || (pseudoClass->mAtom == nsCSSPseudoClasses::focus) || - (pseudoClass->mAtom == nsCSSPseudoClasses::hover)) { + (pseudoClass->mAtom == nsCSSPseudoClasses::hover) || + (pseudoClass->mAtom == nsCSSPseudoClasses::target)) { return PR_TRUE; } pseudoClass = pseudoClass->mNext;