Bug 525608 part 3. Change all style set consumers that ask for a pseudo style context to indicate what they're actually asking for (pseudo-element, anonymous box, or xul tree thing). r=dbaron
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 10 Dec 2009 14:36:05 -0800
changeset 35538 80b631ea5ad11b1126d0df9ffe2cb6a41ceb1db5
parent 35537 db487011d22a0c79aacd4b750b1ee548202235aa
child 35539 732473bebf16066f0ee401a3de67ab6765f5751e
push id10631
push userbzbarsky@mozilla.com
push dateThu, 10 Dec 2009 22:48:24 +0000
treeherdermozilla-central@08b48be6951b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs525608
milestone1.9.3a1pre
Bug 525608 part 3. Change all style set consumers that ask for a pseudo style context to indicate what they're actually asking for (pseudo-element, anonymous box, or xul tree thing). r=dbaron
content/canvas/src/nsCanvasRenderingContext2D.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
layout/base/nsFrameManager.cpp
layout/base/nsLayoutUtils.h
layout/forms/nsButtonFrameRenderer.cpp
layout/forms/nsComboboxControlFrame.cpp
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockFrame.h
layout/generic/nsFrameSetFrame.cpp
layout/generic/nsInlineFrame.cpp
layout/generic/nsTextFrameThebes.cpp
layout/mathml/mathml.css
layout/mathml/nsMathMLFrame.cpp
layout/style/nsCSSPseudoElements.cpp
layout/style/nsCSSPseudoElements.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsStyleAnimation.cpp
layout/style/nsStyleContext.cpp
layout/style/nsStyleContext.h
layout/style/nsStyleSet.cpp
layout/style/nsStyleSet.h
layout/style/nsStyleStruct.h
layout/tables/nsTableFrame.cpp
layout/xul/base/src/tree/src/nsTreeStyleCache.cpp
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -1940,25 +1940,29 @@ nsCanvasRenderingContext2D::SetFont(cons
         rv = CreateFontStyleRule(NS_LITERAL_STRING("10px sans-serif"),
                                  mCSSParser.get(),
                                  document,
                                  getter_AddRefs(parentRule));
         if (NS_FAILED(rv))
             return rv;
         nsCOMArray<nsIStyleRule> parentRules;
         parentRules.AppendObject(parentRule);
-        parentContext = styleSet->ResolveStyleForRules(nsnull, nsnull,
-                                                       nsnull, parentRules);
+        parentContext =
+            styleSet->ResolveStyleForRules(nsnull, nsnull,
+                                           nsCSSPseudoElements::ePseudo_NotPseudoElement,
+                                           nsnull, parentRules);
     }
 
     if (!parentContext)
         return NS_ERROR_FAILURE;
 
     nsRefPtr<nsStyleContext> sc =
-        styleSet->ResolveStyleForRules(parentContext, nsnull, nsnull, rules);
+        styleSet->ResolveStyleForRules(parentContext, nsnull,
+                                       nsCSSPseudoElements::ePseudo_NotPseudoElement,
+                                       nsnull, rules);
     if (!sc)
         return NS_ERROR_FAILURE;
     const nsStyleFont* fontStyle = sc->GetStyleFont();
 
     NS_ASSERTION(fontStyle, "Could not obtain font style");
 
     // use CSS pixels instead of dev pixels to avoid being affected by page zoom
     const PRUint32 aupcp = nsPresContext::AppUnitsPerCSSPixel();
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -82,17 +82,16 @@
 #include "nsICheckboxControlFrame.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsPlaceholderFrame.h"
 #include "nsTableRowGroupFrame.h"
 #include "nsStyleChangeList.h"
 #include "nsIFormControl.h"
 #include "nsCSSAnonBoxes.h"
-#include "nsCSSPseudoElements.h"
 #include "nsIDeviceContext.h"
 #include "nsTextFragment.h"
 #include "nsIAnonymousContentCreator.h"
 #include "nsFrameManager.h"
 #include "nsLegendFrame.h"
 #include "nsIContentIterator.h"
 #include "nsBoxLayoutState.h"
 #include "nsBindingManager.h"
@@ -1820,36 +1819,36 @@ nsCSSFrameConstructor::CreateGeneratedCo
  * aParentFrame/aParentContent, giving the XML element the ::before or
  * ::after style.
  */
 void
 nsCSSFrameConstructor::CreateGeneratedContentItem(nsFrameConstructorState& aState,
                                                   nsIFrame*        aParentFrame,
                                                   nsIContent*      aParentContent,
                                                   nsStyleContext*  aStyleContext,
-                                                  nsIAtom*         aPseudoElement,
+                                                  nsCSSPseudoElements::Type aPseudoElement,
                                                   FrameConstructionItemList& aItems)
 {
   // XXXbz is this ever true?
   if (!aParentContent->IsNodeOfType(nsINode::eELEMENT))
     return;
 
   nsStyleSet *styleSet = mPresShell->StyleSet();
 
   // Probe for the existence of the pseudo-element
   nsRefPtr<nsStyleContext> pseudoStyleContext;
-  pseudoStyleContext = styleSet->ProbePseudoStyleFor(aParentContent,
-                                                     aPseudoElement,
-                                                     aStyleContext);
+  pseudoStyleContext = styleSet->ProbePseudoElementStyle(aParentContent,
+                                                         aPseudoElement,
+                                                         aStyleContext);
   if (!pseudoStyleContext)
     return;
   // |ProbePseudoStyleFor| checked the 'display' property and the
   // |ContentCount()| of the 'content' property for us.
   nsCOMPtr<nsINodeInfo> nodeInfo;
-  nsIAtom* elemName = aPseudoElement == nsCSSPseudoElements::before ?
+  nsIAtom* elemName = aPseudoElement == nsCSSPseudoElements::ePseudo_before ?
     nsGkAtoms::mozgeneratedcontentbefore : nsGkAtoms::mozgeneratedcontentafter;
   nodeInfo = mDocument->NodeInfoManager()->GetNodeInfo(elemName, nsnull,
                                                        kNameSpaceID_None);
   nsCOMPtr<nsIContent> container;
   nsresult rv = NS_NewXMLElement(getter_AddRefs(container), nodeInfo);
   if (NS_FAILED(rv))
     return;
   container->SetNativeAnonymous();
@@ -2026,17 +2025,17 @@ nsCSSFrameConstructor::ConstructTable(ns
   nsStyleContext* const styleContext = aItem.mStyleContext;
   const PRUint32 nameSpaceID = aItem.mNameSpaceID;
   
   nsresult rv = NS_OK;
 
   // create the pseudo SC for the outer table as a child of the inner SC
   nsRefPtr<nsStyleContext> outerStyleContext;
   outerStyleContext = mPresShell->StyleSet()->
-    ResolvePseudoStyleFor(content, nsCSSAnonBoxes::tableOuter, styleContext);
+    ResolveAnonymousBoxStyle(nsCSSAnonBoxes::tableOuter, styleContext);
 
   // Create the outer table frame which holds the caption and inner table frame
   nsIFrame* newFrame;
 #ifdef MOZ_MATHML
   if (kNameSpaceID_MathML == nameSpaceID)
     newFrame = NS_NewMathMLmtableOuterFrame(mPresShell, outerStyleContext);
   else
 #endif
@@ -2230,17 +2229,17 @@ nsCSSFrameConstructor::ConstructTableCel
 
   // Initialize the table cell frame
   InitAndRestoreFrame(aState, content, aParentFrame, nsnull, newFrame);
   nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
   
   // Resolve pseudo style and initialize the body cell frame
   nsRefPtr<nsStyleContext> innerPseudoStyle;
   innerPseudoStyle = mPresShell->StyleSet()->
-    ResolvePseudoStyleFor(content, nsCSSAnonBoxes::cellContent, styleContext);
+    ResolveAnonymousBoxStyle(nsCSSAnonBoxes::cellContent, styleContext);
 
   // Create a block frame that will format the cell's content
   PRBool isBlock;
   nsIFrame* cellInnerFrame;
 #ifdef MOZ_MATHML
   if (kNameSpaceID_MathML == nameSpaceID) {
     cellInnerFrame = NS_NewMathMLmtdInnerFrame(mPresShell, innerPseudoStyle);
     isBlock = PR_FALSE;
@@ -2665,19 +2664,18 @@ nsCSSFrameConstructor::ConstructRootFram
   {
     styleSet->SetBindingManager(mDocument->BindingManager());
   }
 
   // --------- BUILD VIEWPORT -----------
   nsIFrame*                 viewportFrame = nsnull;
   nsRefPtr<nsStyleContext> viewportPseudoStyle;
 
-  viewportPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
-                                                        nsCSSAnonBoxes::viewport,
-                                                        nsnull);
+  viewportPseudoStyle =
+    styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::viewport, nsnull);
 
   viewportFrame = NS_NewViewportFrame(mPresShell, viewportPseudoStyle);
 
   // XXXbz do we _have_ to pass a null content pointer to that frame?
   // Would it really kill us to pass in the root element or something?
   // What would that break?
   viewportFrame->Init(nsnull, nsnull, nsnull);
 
@@ -2859,38 +2857,36 @@ nsCSSFrameConstructor::SetUpDocElementCo
   nsFrameConstructorState state(mPresShell, nsnull, nsnull, nsnull);
 
   // Start off with the viewport as parent; we'll adjust it as needed.
   nsIFrame* parentFrame = viewportFrame;
 
   nsStyleSet* styleSet = mPresShell->StyleSet();
   // If paginated, make sure we don't put scrollbars in
   if (!isScrollable) {
-    rootPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
-                                                      rootPseudo,
-                                                      viewportPseudoStyle);
+    rootPseudoStyle = styleSet->ResolveAnonymousBoxStyle(rootPseudo,
+                                                         viewportPseudoStyle);
   } else {
       if (rootPseudo == nsCSSAnonBoxes::canvas) {
         rootPseudo = nsCSSAnonBoxes::scrolledCanvas;
       } else {
         NS_ASSERTION(rootPseudo == nsCSSAnonBoxes::pageSequence,
                      "Unknown root pseudo");
         rootPseudo = nsCSSAnonBoxes::scrolledPageSequence;
       }
 
       // Build the frame. We give it the content we are wrapping which is the
       // document element, the root frame, the parent view port frame, and we
       // should get back the new frame and the scrollable view if one was
       // created.
 
       // resolve a context for the scrollframe
       nsRefPtr<nsStyleContext>  styleContext;
-      styleContext = styleSet->ResolvePseudoStyleFor(nsnull,
-                                                     nsCSSAnonBoxes::viewportScroll,
-                                                     viewportPseudoStyle);
+      styleContext = styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::viewportScroll,
+                                                        viewportPseudoStyle);
 
       // Note that the viewport scrollframe is always built with
       // overflow:auto style. This forces the scroll frame to create
       // anonymous content for both scrollbars. This is necessary even
       // if the HTML or BODY elements are overriding the viewport
       // scroll style to 'hidden' --- dynamic style changes might put
       // scrollbars back on the viewport and we don't want to have to
       // reframe the viewport to create the scrollbar content.
@@ -2953,32 +2949,31 @@ nsCSSFrameConstructor::ConstructPageFram
                                           nsIFrame*      aPrevPageFrame,
                                           nsIFrame*&     aPageFrame,
                                           nsIFrame*&     aCanvasFrame)
 {
   nsStyleContext* parentStyleContext = aParentFrame->GetStyleContext();
   nsStyleSet *styleSet = aPresShell->StyleSet();
 
   nsRefPtr<nsStyleContext> pagePseudoStyle;
-  pagePseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
-                                                    nsCSSAnonBoxes::page,
-                                                    parentStyleContext);
+  pagePseudoStyle = styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::page,
+                                                       parentStyleContext);
 
   aPageFrame = NS_NewPageFrame(aPresShell, pagePseudoStyle);
   if (NS_UNLIKELY(!aPageFrame))
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Initialize the page frame and force it to have a view. This makes printing of
   // the pages easier and faster.
   aPageFrame->Init(nsnull, aParentFrame, aPrevPageFrame);
 
   nsRefPtr<nsStyleContext> pageContentPseudoStyle;
-  pageContentPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
-                                                           nsCSSAnonBoxes::pageContent,
-                                                           pagePseudoStyle);
+  pageContentPseudoStyle =
+    styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::pageContent,
+                                       pagePseudoStyle);
 
   nsIFrame* pageContentFrame = NS_NewPageContentFrame(aPresShell, pageContentPseudoStyle);
   if (NS_UNLIKELY(!pageContentFrame))
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Initialize the page content frame and force it to have a view. Also make it the
   // containing block for fixed elements which are repeated on every page.
   nsIFrame* prevPageContentFrame = nsnull;
@@ -2986,19 +2981,18 @@ nsCSSFrameConstructor::ConstructPageFram
     prevPageContentFrame = aPrevPageFrame->GetFirstChild(nsnull);
     NS_ASSERTION(prevPageContentFrame, "missing page content frame");
   }
   pageContentFrame->Init(nsnull, aPageFrame, prevPageContentFrame);
   SetInitialSingleChild(aPageFrame, pageContentFrame);
   mFixedContainingBlock = pageContentFrame;
 
   nsRefPtr<nsStyleContext> canvasPseudoStyle;
-  canvasPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
-                                                      nsCSSAnonBoxes::canvas,
-                                                      pageContentPseudoStyle);
+  canvasPseudoStyle = styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::canvas,
+                                                         pageContentPseudoStyle);
 
   aCanvasFrame = NS_NewCanvasFrame(aPresShell, canvasPseudoStyle);
   if (NS_UNLIKELY(!aCanvasFrame))
     return NS_ERROR_OUT_OF_MEMORY;
 
   nsIFrame* prevCanvasFrame = nsnull;
   if (prevPageContentFrame) {
     prevCanvasFrame = prevPageContentFrame->GetFirstChild(nsnull);
@@ -3079,19 +3073,18 @@ nsCSSFrameConstructor::ConstructButtonFr
     buttonFrame->Destroy();
     return rv;
   }
   // See if we need to create a view
   nsHTMLContainerFrame::CreateViewForFrame(buttonFrame, PR_FALSE);
 
   nsRefPtr<nsStyleContext> innerBlockContext;
   innerBlockContext =
-    mPresShell->StyleSet()->ResolvePseudoStyleFor(content,
-                                                  nsCSSAnonBoxes::buttonContent,
-                                                  styleContext);
+    mPresShell->StyleSet()->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::buttonContent,
+                                                     styleContext);
                                                                
   nsIFrame* blockFrame = NS_NewBlockFrame(mPresShell, innerBlockContext,
                                           NS_BLOCK_FLOAT_MGR);
 
   if (NS_UNLIKELY(!blockFrame)) {
     buttonFrame->Destroy();
     return NS_ERROR_OUT_OF_MEMORY;
   }
@@ -3219,19 +3212,18 @@ nsCSSFrameConstructor::ConstructSelectFr
       // Combobox - Old Native Implementation
       ///////////////////////////////////////////////////////////////////
       nsIComboboxControlFrame* comboBox = do_QueryFrame(comboboxFrame);
       NS_ASSERTION(comboBox, "NS_NewComboboxControlFrame returned frame that "
                              "doesn't implement nsIComboboxControlFrame");
 
         // Resolve pseudo element style for the dropdown list
       nsRefPtr<nsStyleContext> listStyle;
-      listStyle = mPresShell->StyleSet()->ResolvePseudoStyleFor(content,
-                                                                nsCSSAnonBoxes::dropDownList, 
-                                                                styleContext);
+      listStyle = mPresShell->StyleSet()->
+        ResolveAnonymousBoxStyle(nsCSSAnonBoxes::dropDownList, styleContext);
 
         // Create a listbox
       nsIFrame* listFrame = NS_NewListControlFrame(mPresShell, listStyle);
 
         // Notify the listbox that it is being used as a dropdown list.
       nsIListControlFrame * listControlFrame = do_QueryFrame(listFrame);
       if (listControlFrame) {
         listControlFrame->SetComboboxFrame(comboboxFrame);
@@ -3417,20 +3409,18 @@ nsCSSFrameConstructor::ConstructFieldSet
                       nsnull, newFrame);
 
   // See if we need to create a view, e.g. the frame is absolutely
   // positioned
   nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
 
   // Resolve style and initialize the frame
   nsRefPtr<nsStyleContext> fieldsetContentStyle;
-  fieldsetContentStyle =
-    mPresShell->StyleSet()->ResolvePseudoStyleFor(content,
-                                                  nsCSSAnonBoxes::fieldsetContent,
-                                                  styleContext);
+  fieldsetContentStyle = mPresShell->StyleSet()->
+    ResolveAnonymousBoxStyle(nsCSSAnonBoxes::fieldsetContent, styleContext);
 
   nsIFrame* blockFrame = NS_NewBlockFrame(mPresShell, fieldsetContentStyle,
                                           NS_BLOCK_FLOAT_MGR |
                                           NS_BLOCK_MARGIN_ROOT);
   InitAndRestoreFrame(aState, content, newFrame, nsnull, blockFrame);
 
   nsresult rv = aState.AddChild(newFrame, aFrameItems, content, styleContext,
                                 aParentFrame);
@@ -4386,19 +4376,18 @@ nsCSSFrameConstructor::BeginBuildingScro
   // consistent anyway.
   CreateAnonymousFrames(aState, aContent, gfxScrollFrame, nsnull,
                         anonymousItems);
 
   aNewFrame = gfxScrollFrame;
 
   // we used the style that was passed in. So resolve another one.
   nsStyleSet *styleSet = mPresShell->StyleSet();
-  nsStyleContext* aScrolledChildStyle = styleSet->ResolvePseudoStyleFor(aContent,
-                                                                        aScrolledPseudo,
-                                                                        contentStyle).get();
+  nsStyleContext* aScrolledChildStyle =
+    styleSet->ResolveAnonymousBoxStyle(aScrolledPseudo, contentStyle).get();
 
   if (gfxScrollFrame) {
      gfxScrollFrame->SetInitialChildList(nsnull, anonymousItems);
   }
 
   return aScrolledChildStyle;
 }
 
@@ -4747,19 +4736,19 @@ nsCSSFrameConstructor::FlushAccumulatedB
     return NS_OK;
   }
 
   nsStyleContext* parentContext =
     nsFrame::CorrectStyleParentFrame(aParentFrame,
                                      nsCSSAnonBoxes::mozMathMLAnonymousBlock)->GetStyleContext(); 
   nsStyleSet *styleSet = mPresShell->StyleSet();
   nsRefPtr<nsStyleContext> blockContext;
-  blockContext = styleSet->ResolvePseudoStyleFor(aContent,
-                                                 nsCSSAnonBoxes::mozMathMLAnonymousBlock,
-                                                 parentContext);
+  blockContext = styleSet->
+    ResolveAnonymousBoxStyle(nsCSSAnonBoxes::mozMathMLAnonymousBlock,
+                             parentContext);
 
   // then, create a block frame that will wrap the child frames. Make it a
   // MathML frame so that Get(Absolute/Float)ContainingBlockFor know that this
   // is not a suitable block.
   nsIFrame* blockFrame = NS_NewMathMLmathBlockFrame(mPresShell, blockContext,
                           NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT);
   if (NS_UNLIKELY(!blockFrame))
     return NS_ERROR_OUT_OF_MEMORY;
@@ -5062,18 +5051,17 @@ nsCSSFrameConstructor::ConstructSVGForei
   nsresult rv = aState.AddChild(newFrame, aFrameItems, content, styleContext,
                                 aParentFrame, PR_FALSE, PR_FALSE);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   nsRefPtr<nsStyleContext> innerPseudoStyle;
   innerPseudoStyle = mPresShell->StyleSet()->
-    ResolvePseudoStyleFor(content,
-                          nsCSSAnonBoxes::mozSVGForeignContent, styleContext);
+    ResolveAnonymousBoxStyle(nsCSSAnonBoxes::mozSVGForeignContent, styleContext);
 
   nsIFrame* blockFrame = NS_NewBlockFrame(mPresShell, innerPseudoStyle,
                                           NS_BLOCK_FLOAT_MGR |
                                           NS_BLOCK_MARGIN_ROOT);
   if (NS_UNLIKELY(!blockFrame)) {
     newFrame->Destroy();
     return NS_ERROR_OUT_OF_MEMORY;
   }
@@ -5106,18 +5094,18 @@ nsCSSFrameConstructor::AddPageBreakItem(
 {
   nsRefPtr<nsStyleContext> pseudoStyle;
   // Use the same parent style context that |aMainStyleContext| has, since
   // that's easier to re-resolve and it doesn't matter in practice.
   // (Getting different parents can result in framechange hints, e.g.,
   // for user-modify.)
   pseudoStyle =
     mPresShell->StyleSet()->
-      ResolvePseudoStyleFor(nsnull, nsCSSAnonBoxes::pageBreak,
-                            aMainStyleContext->GetParent());
+      ResolveAnonymousBoxStyle(nsCSSAnonBoxes::pageBreak,
+                               aMainStyleContext->GetParent());
 
   NS_ASSERTION(pseudoStyle->GetStyleDisplay()->mDisplay ==
                  NS_STYLE_DISPLAY_BLOCK, "Unexpected display");
 
   static const FrameConstructionData sPageBreakData =
     FCDATA_DECL(FCDATA_SKIP_FRAMEMAP, NS_NewPageBreakFrame);
 
   // Lie about the tag and namespace so we don't trigger anything
@@ -5707,17 +5695,17 @@ AdjustAppendParentForAfterContent(nsPres
                                   nsIContent* aContainer,
                                   nsIFrame* aParentFrame,
                                   nsIFrame** aAfterFrame)
 {
   // See if the parent has an :after pseudo-element.  Check for the presence
   // of style first, since nsLayoutUtils::GetAfterFrame is sorta expensive.
   nsStyleContext* parentStyle = aParentFrame->GetStyleContext();
   if (nsLayoutUtils::HasPseudoStyle(aContainer, parentStyle,
-                                    nsCSSPseudoElements::after,
+                                    nsCSSPseudoElements::ePseudo_after,
                                     aPresContext)) {
     nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(aParentFrame);
     if (afterFrame) {
       *aAfterFrame = afterFrame;
       return afterFrame->GetParent();
     }
   }
 
@@ -9242,42 +9230,44 @@ nsCSSFrameConstructor::RecreateFramesFor
 // Block frame construction code
 
 already_AddRefed<nsStyleContext>
 nsCSSFrameConstructor::GetFirstLetterStyle(nsIContent* aContent,
                                            nsStyleContext* aStyleContext)
 {
   if (aContent) {
     return mPresShell->StyleSet()->
-      ResolvePseudoStyleFor(aContent,
-                            nsCSSPseudoElements::firstLetter, aStyleContext);
+      ResolvePseudoElementStyle(aContent,
+                                nsCSSPseudoElements::ePseudo_firstLetter,
+                                aStyleContext);
   }
   return nsnull;
 }
 
 already_AddRefed<nsStyleContext>
 nsCSSFrameConstructor::GetFirstLineStyle(nsIContent* aContent,
                                          nsStyleContext* aStyleContext)
 {
   if (aContent) {
     return mPresShell->StyleSet()->
-      ResolvePseudoStyleFor(aContent,
-                            nsCSSPseudoElements::firstLine, aStyleContext);
+      ResolvePseudoElementStyle(aContent,
+                                nsCSSPseudoElements::ePseudo_firstLine,
+                                aStyleContext);
   }
   return nsnull;
 }
 
 // Predicate to see if a given content (block element) has
 // first-letter style applied to it.
 PRBool
 nsCSSFrameConstructor::ShouldHaveFirstLetterStyle(nsIContent* aContent,
                                                   nsStyleContext* aStyleContext)
 {
   return nsLayoutUtils::HasPseudoStyle(aContent, aStyleContext,
-                                       nsCSSPseudoElements::firstLetter,
+                                       nsCSSPseudoElements::ePseudo_firstLetter,
                                        mPresShell->GetPresContext());
 }
 
 PRBool
 nsCSSFrameConstructor::HasFirstLetterStyle(nsIFrame* aBlockFrame)
 {
   NS_PRECONDITION(aBlockFrame, "Need a frame");
   NS_ASSERTION(nsLayoutUtils::GetAsBlock(aBlockFrame),
@@ -9287,17 +9277,17 @@ nsCSSFrameConstructor::HasFirstLetterSty
 }
 
 PRBool
 nsCSSFrameConstructor::ShouldHaveFirstLineStyle(nsIContent* aContent,
                                                 nsStyleContext* aStyleContext)
 {
   PRBool hasFirstLine =
     nsLayoutUtils::HasPseudoStyle(aContent, aStyleContext,
-                                  nsCSSPseudoElements::firstLine,
+                                  nsCSSPseudoElements::ePseudo_firstLine,
                                   mPresShell->GetPresContext());
   if (hasFirstLine) {
     // But disable for fieldsets
     PRInt32 namespaceID;
     nsIAtom* tag = mDocument->BindingManager()->ResolveTag(aContent,
                                                            &namespaceID);
     // This check must match the one in FindHTMLData.
     hasFirstLine = tag != nsGkAtoms::fieldset ||
@@ -9513,19 +9503,17 @@ nsCSSFrameConstructor::CreateNeededTable
     nsIContent* parentContent = aParentFrame->GetContent();
 
     if (pseudoType == nsCSSAnonBoxes::table &&
         parentStyle->GetStyleDisplay()->mDisplay == NS_STYLE_DISPLAY_INLINE) {
       pseudoType = nsCSSAnonBoxes::inlineTable;
     }
 
     nsRefPtr<nsStyleContext> wrapperStyle =
-      mPresShell->StyleSet()->ResolvePseudoStyleFor(parentContent,
-                                                    pseudoType,
-                                                    parentStyle);
+      mPresShell->StyleSet()->ResolveAnonymousBoxStyle(pseudoType, parentStyle);
     FrameConstructionItem* newItem =
       new FrameConstructionItem(&pseudoData.mFCData,
                                 // Use the content of our parent frame
                                 parentContent,
                                 // Lie about the tag; it doesn't matter anyway
                                 pseudoType,
                                 // The namespace does matter, however; it needs
                                 // to match that of our first child item to
@@ -9668,34 +9656,34 @@ nsCSSFrameConstructor::ProcessChildren(n
     // special block styles because in some cases involving table pseudo-frames
     // it has nothing to do with the parent frame's desired behavior.
     nsStyleContext* styleContext;
 
     if (aCanHaveGeneratedContent) {
       styleContext =
         nsFrame::CorrectStyleParentFrame(aFrame, nsnull)->GetStyleContext();
       // Probe for generated content before
-      CreateGeneratedContentItem(aState, aFrame, aContent,
-                                 styleContext, nsCSSPseudoElements::before,
+      CreateGeneratedContentItem(aState, aFrame, aContent, styleContext,
+                                 nsCSSPseudoElements::ePseudo_before,
                                  itemsToConstruct);
     }
 
     ChildIterator iter, last;
     for (ChildIterator::Init(aContent, &iter, &last);
          iter != last;
          ++iter) {
       PRInt32 i = iter.XBLInvolved() ? -1 : iter.position();
       AddFrameConstructionItems(aState, *iter, i, aFrame, itemsToConstruct);
     }
     itemsToConstruct.SetParentHasNoXBLChildren(!iter.XBLInvolved());
 
     if (aCanHaveGeneratedContent) {
       // Probe for generated content after
-      CreateGeneratedContentItem(aState, aFrame, aContent,
-                                 styleContext, nsCSSPseudoElements::after,
+      CreateGeneratedContentItem(aState, aFrame, aContent, styleContext,
+                                 nsCSSPseudoElements::ePseudo_after,
                                  itemsToConstruct);
     }
   }
 
   rv = ConstructFramesFromItemList(aState, itemsToConstruct, aFrame,
                                    aFrameItems);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -9738,19 +9726,18 @@ nsCSSFrameConstructor::ProcessChildren(n
                                     message,
                                     params, NS_ARRAY_LENGTH(params),
                                     mDocument->GetDocumentURI(),
                                     EmptyString(), 0, 0, // not useful
                                     nsIScriptError::warningFlag,
                                     "FrameConstructor");
 
     nsRefPtr<nsStyleContext> blockSC = mPresShell->StyleSet()->
-      ResolvePseudoStyleFor(aContent,
-                            nsCSSAnonBoxes::mozXULAnonymousBlock,
-                            frameStyleContext);
+      ResolveAnonymousBoxStyle(nsCSSAnonBoxes::mozXULAnonymousBlock,
+                               frameStyleContext);
     nsIFrame *blockFrame = NS_NewBlockFrame(mPresShell, blockSC);
     // We might, in theory, want to set NS_BLOCK_FLOAT_MGR and
     // NS_BLOCK_MARGIN_ROOT, but I think it's a bad idea given that
     // a real block placed here wouldn't get those set on it.
 
     InitAndRestoreFrame(aState, aContent, aFrame, nsnull,
                         blockFrame, PR_FALSE);
 
@@ -10690,18 +10677,17 @@ nsCSSFrameConstructor::ConstructBlock(ns
     if (!columnSetFrame) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     InitAndRestoreFrame(aState, aContent, aParentFrame, nsnull, columnSetFrame);
     // See if we need to create a view
     nsHTMLContainerFrame::CreateViewForFrame(columnSetFrame, PR_FALSE);
     blockStyle = mPresShell->StyleSet()->
-      ResolvePseudoStyleFor(aContent, nsCSSAnonBoxes::columnContent,
-                            aStyleContext);
+      ResolveAnonymousBoxStyle(nsCSSAnonBoxes::columnContent, aStyleContext);
     parent = columnSetFrame;
     *aNewFrame = columnSetFrame;
 
     SetInitialSingleChild(columnSetFrame, blockFrame);
   }
 
   blockFrame->SetStyleContextWithoutNotification(blockStyle);
   InitAndRestoreFrame(aState, aContent, parent, nsnull, blockFrame);
@@ -10895,21 +10881,20 @@ nsCSSFrameConstructor::CreateIBSiblings(
 {
   nsIContent* content = aInitialInline->GetContent();
   nsStyleContext* styleContext = aInitialInline->GetStyleContext();
   nsIFrame* parentFrame = aInitialInline->GetParent();
 
   // Resolve the right style context for our anonymous blocks.
   nsRefPtr<nsStyleContext> blockSC =
     mPresShell->StyleSet()->
-      ResolvePseudoStyleFor(content,
-                            aIsPositioned ?
-                              nsCSSAnonBoxes::mozAnonymousPositionedBlock :
-                              nsCSSAnonBoxes::mozAnonymousBlock,
-                            styleContext);
+      ResolveAnonymousBoxStyle(aIsPositioned ?
+                                 nsCSSAnonBoxes::mozAnonymousPositionedBlock :
+                                 nsCSSAnonBoxes::mozAnonymousBlock,
+                               styleContext);
 
   nsIFrame* lastNewInline = aInitialInline->GetFirstContinuation();
   do {
     // On entry to this loop aChildItems is not empty and the first frame in it
     // is block-level.
     NS_PRECONDITION(aChildItems.NotEmpty(), "Should have child items");
     NS_PRECONDITION(!IsInlineOutside(aChildItems.FirstChild()),
                     "Must have list starting with block");
@@ -10977,18 +10962,18 @@ nsCSSFrameConstructor::BuildInlineChildI
   // XXXbz should we preallocate aParentItem.mChildItems to some sane
   // length?  Maybe even to parentContent->GetChildCount()?
   nsFrameConstructorState::PendingBindingAutoPusher
     pusher(aState, aParentItem.mPendingBinding);
 
   // Probe for generated content before
   nsStyleContext* const parentStyleContext = aParentItem.mStyleContext;
   nsIContent* const parentContent = aParentItem.mContent;
-  CreateGeneratedContentItem(aState, nsnull, parentContent,
-                             parentStyleContext, nsCSSPseudoElements::before,
+  CreateGeneratedContentItem(aState, nsnull, parentContent, parentStyleContext,
+                             nsCSSPseudoElements::ePseudo_before,
                              aParentItem.mChildItems);
 
   ChildIterator iter, last;
   for (ChildIterator::Init(parentContent, &iter, &last);
        iter != last;
        ++iter) {
     // Manually check for comments/PIs, since we do't have a frame to pass to
     // AddFrameConstructionItems.  We know our parent is a non-replaced inline,
@@ -11005,18 +10990,18 @@ nsCSSFrameConstructor::BuildInlineChildI
     PRInt32 i = iter.XBLInvolved() ? -1 : iter.position();
     AddFrameConstructionItemsInternal(aState, content, nsnull, content->Tag(),
                                       content->GetNameSpaceID(), i, childContext,
                                       ITEM_ALLOW_XBL_BASE | ITEM_ALLOW_PAGE_BREAK,
                                       aParentItem.mChildItems);
   }
 
   // Probe for generated content after
-  CreateGeneratedContentItem(aState, nsnull, parentContent,
-                             parentStyleContext, nsCSSPseudoElements::after,
+  CreateGeneratedContentItem(aState, nsnull, parentContent, parentStyleContext,
+                             nsCSSPseudoElements::ePseudo_after,
                              aParentItem.mChildItems);
 
   aParentItem.mIsAllInline = aParentItem.mChildItems.AreAllItemsInline();
 }
 
 PRBool
 nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState,
                                            nsIFrame* aContainingBlock,
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -47,16 +47,17 @@
 #include "nsILayoutHistoryState.h"
 #include "nsIXBLService.h"
 #include "nsQuoteList.h"
 #include "nsCounterManager.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsThreadUtils.h"
 #include "nsPageContentFrame.h"
+#include "nsCSSPseudoElements.h"
 
 class nsIDocument;
 struct nsFrameItems;
 struct nsAbsoluteItems;
 class nsStyleContext;
 struct nsStyleContent;
 struct nsStyleDisplay;
 class nsIPresShell;
@@ -431,21 +432,21 @@ private:
    * @param aContentIndex is the index of the content item to create
    */
   already_AddRefed<nsIContent> CreateGeneratedContent(nsFrameConstructorState& aState,
                                                       nsIContent*     aParentContent,
                                                       nsStyleContext* aStyleContext,
                                                       PRUint32        aContentIndex);
 
   // aFrame may be null; this method doesn't use it directly in any case.
-  void CreateGeneratedContentItem(nsFrameConstructorState& aState,
-                                  nsIFrame*                aFrame,
-                                  nsIContent*              aContent,
-                                  nsStyleContext*          aStyleContext,
-                                  nsIAtom*                 aPseudoElement,
+  void CreateGeneratedContentItem(nsFrameConstructorState&   aState,
+                                  nsIFrame*                  aFrame,
+                                  nsIContent*                aContent,
+                                  nsStyleContext*            aStyleContext,
+                                  nsCSSPseudoElements::Type  aPseudoElement,
                                   FrameConstructionItemList& aItems);
 
   // This method can change aFrameList: it can chop off the beginning and put
   // it in aParentFrame while putting the remainder into a special sibling of
   // aParentFrame.  aPrevSibling must be the frame after which aFrameList is to
   // be placed on aParentFrame's principal child list.  It may be null if
   // aFrameList is being added at the beginning of the child list.
   nsresult AppendFrames(nsFrameConstructorState&       aState,
--- a/layout/base/nsFrameManager.cpp
+++ b/layout/base/nsFrameManager.cpp
@@ -944,16 +944,17 @@ TryStartingTransition(nsPresContext *aPr
     aPresContext->TransitionManager()->StyleContextChanged(
       aContent, aOldStyleContext, *aNewStyleContext);
   if (coverRule) {
     nsCOMArray<nsIStyleRule> rules;
     rules.AppendObject(coverRule);
     *aNewStyleContext = aPresContext->StyleSet()->ResolveStyleForRules(
                      (*aNewStyleContext)->GetParent(),
                      (*aNewStyleContext)->GetPseudo(),
+                     (*aNewStyleContext)->GetPseudoType(),
                      (*aNewStyleContext)->GetRuleNode(),
                      rules);
   }
 }
 
 nsresult
 nsFrameManager::ReParentStyleContext(nsIFrame* aFrame)
 {
@@ -1228,16 +1229,17 @@ nsFrameManager::ReResolveStyleContext(ns
   PRBool isVisible = aFrame->GetStyleVisibility()->IsVisible();
 #endif
 
   // XXXbz the nsIFrame constructor takes an nsStyleContext, so how
   // could oldContext be null?
   if (oldContext) {
     oldContext->AddRef();
     nsIAtom* const pseudoTag = oldContext->GetPseudo();
+    const nsCSSPseudoElements::Type pseudoType = oldContext->GetPseudoType();
     nsIContent* localContent = aFrame->GetContent();
     // |content| is the node that we used for rule matching of
     // normal elements (not pseudo-elements) and for which we generate
     // framechange hints if we need them.
     // XXXldb Why does it make sense to use aParentContent?  (See
     // comment above assertion at start of function.)
     nsIContent* content = localContent ? localContent : aParentContent;
 
@@ -1329,39 +1331,45 @@ nsFrameManager::ReResolveStyleContext(ns
       // boxes and perhaps other cases.
       // See also the comment above the assertion at the start of this
       // function.
       nsIContent* pseudoContent =
           aParentContent ? aParentContent : localContent;
       if (pseudoTag == nsCSSPseudoElements::before ||
           pseudoTag == nsCSSPseudoElements::after) {
         // XXX what other pseudos do we need to treat like this?
-        newContext = styleSet->ProbePseudoStyleFor(pseudoContent,
-                                                   pseudoTag,
-                                                   parentContext);
+        newContext = styleSet->ProbePseudoElementStyle(pseudoContent,
+                                                       pseudoType,
+                                                       parentContext);
         if (!newContext) {
           // This pseudo should no longer exist; gotta reframe
           NS_UpdateHint(aMinChange, nsChangeHint_ReconstructFrame);
           aChangeList->AppendChange(aFrame, pseudoContent,
                                     nsChangeHint_ReconstructFrame);
           // We're reframing anyway; just keep the same context
           newContext = oldContext;
         }
+      } else if (pseudoType == nsCSSPseudoElements::ePseudo_AnonBox) {
+        newContext = styleSet->ResolveAnonymousBoxStyle(pseudoTag,
+                                                        parentContext);
       } else {
+        // Don't expect XUL tree stuff here, since it needs a comparator and
+        // all.
+        NS_ASSERTION(pseudoType <
+                       nsCSSPseudoElements::ePseudo_PseudoElementCount,
+                     "Unexpected pseudo type");
         if (pseudoTag == nsCSSPseudoElements::firstLetter) {
           NS_ASSERTION(aFrame->GetType() == nsGkAtoms::letterFrame, 
                        "firstLetter pseudoTag without a nsFirstLetterFrame");
           nsBlockFrame* block = nsBlockFrame::GetNearestAncestorBlock(aFrame);
           pseudoContent = block->GetContent();
-        } else if (pseudoTag == nsCSSAnonBoxes::pageBreak) {
-          pseudoContent = nsnull;
         }
-        newContext = styleSet->ResolvePseudoStyleFor(pseudoContent,
-                                                     pseudoTag,
-                                                     parentContext);
+        newContext = styleSet->ResolvePseudoElementStyle(pseudoContent,
+                                                         pseudoType,
+                                                         parentContext);
       }
     }
     else {
       NS_ASSERTION(localContent,
                    "non pseudo-element frame without content node");
       newContext = styleSet->ResolveStyleFor(content, parentContext);
     }
     NS_ASSERTION(newContext, "failed to get new style context");
@@ -1401,22 +1409,35 @@ nsFrameManager::ReResolveStyleContext(ns
     // do additional contexts 
     PRInt32 contextIndex = -1;
     while (1 == 1) {
       nsStyleContext* oldExtraContext = nsnull;
       oldExtraContext = aFrame->GetAdditionalStyleContext(++contextIndex);
       if (oldExtraContext) {
         nsRefPtr<nsStyleContext> newExtraContext;
         nsIAtom* const extraPseudoTag = oldExtraContext->GetPseudo();
+        const nsCSSPseudoElements::Type extraPseudoType =
+          oldExtraContext->GetPseudoType();
         NS_ASSERTION(extraPseudoTag &&
                      extraPseudoTag != nsCSSAnonBoxes::mozNonElement,
                      "extra style context is not pseudo element");
-        newExtraContext = styleSet->ResolvePseudoStyleFor(content,
-                                                          extraPseudoTag,
-                                                          newContext);
+        if (extraPseudoType == nsCSSPseudoElements::ePseudo_AnonBox) {
+          newExtraContext = styleSet->ResolveAnonymousBoxStyle(extraPseudoTag,
+                                                               newContext);
+        }
+        else {
+          // Don't expect XUL tree stuff here, since it needs a comparator and
+          // all.
+          NS_ASSERTION(extraPseudoType <
+                         nsCSSPseudoElements::ePseudo_PseudoElementCount,
+                       "Unexpected type");
+          newExtraContext = styleSet->ResolvePseudoElementStyle(content,
+                                                                extraPseudoType,
+                                                                newContext);
+        }
         if (newExtraContext) {
           if (oldExtraContext != newExtraContext) {
             aMinChange = CaptureChange(oldExtraContext, newExtraContext,
                                        aFrame, content, aChangeList,
                                        aMinChange, assumeDifferenceHint);
             if (!(aMinChange & nsChangeHint_ReconstructFrame)) {
               aFrame->SetAdditionalStyleContext(contextIndex, newExtraContext);
             }
@@ -1484,17 +1505,17 @@ nsFrameManager::ReResolveStyleContext(ns
         // Check for a new :before pseudo and an existing :before
         // frame, but only if the frame is the first continuation.
         nsIFrame* prevContinuation = aFrame->GetPrevContinuation();
         if (!prevContinuation) {
           // Checking for a :before frame is cheaper than getting the
           // :before style context.
           if (!nsLayoutUtils::GetBeforeFrame(aFrame) &&
               nsLayoutUtils::HasPseudoStyle(localContent, newContext,
-                                            nsCSSPseudoElements::before,
+                                            nsCSSPseudoElements::ePseudo_before,
                                             aPresContext)) {
             // Have to create the new :before frame
             NS_UpdateHint(aMinChange, nsChangeHint_ReconstructFrame);
             aChangeList->AppendChange(aFrame, content,
                                       nsChangeHint_ReconstructFrame);
           }
         }
       }
@@ -1510,17 +1531,17 @@ nsFrameManager::ReResolveStyleContext(ns
         // Check for new :after content, but only if the frame is the
         // last continuation.
         nsIFrame* nextContinuation = aFrame->GetNextContinuation();
 
         if (!nextContinuation) {
           // Getting the :after frame is more expensive than getting the pseudo
           // context, so get the pseudo context first.
           if (nsLayoutUtils::HasPseudoStyle(localContent, newContext,
-                                            nsCSSPseudoElements::after,
+                                            nsCSSPseudoElements::ePseudo_after,
                                             aPresContext) &&
               !nsLayoutUtils::GetAfterFrame(aFrame)) {
             // have to create the new :after frame
             NS_UpdateHint(aMinChange, nsChangeHint_ReconstructFrame);
             aChangeList->AppendChange(aFrame, content,
                                       nsChangeHint_ReconstructFrame);
           }
         }      
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -59,16 +59,17 @@ class nsClientRectList;
 #include "nsStyleSet.h"
 #include "nsIView.h"
 #include "nsIFrame.h"
 #include "nsThreadUtils.h"
 #include "nsIPresShell.h"
 #include "nsIPrincipal.h"
 #include "gfxPattern.h"
 #include "imgIContainer.h"
+#include "nsCSSPseudoElements.h"
 
 class nsBlockFrame;
 class nsTextFragment;
 
 /**
  * nsLayoutUtils is a namespace class used for various helper
  * functions that are useful in multiple places in layout.  The goal
  * is not to define multiple copies of the same static helper.
@@ -322,32 +323,31 @@ public:
 
   /**
    * HasPseudoStyle returns PR_TRUE if aContent (whose primary style
    * context is aStyleContext) has the aPseudoElement pseudo-style
    * attached to it; returns PR_FALSE otherwise.
    *
    * @param aContent the content node we're looking at
    * @param aStyleContext aContent's style context
-   * @param aPseudoElement the name of the pseudo style we care about
+   * @param aPseudoElement the id of the pseudo style we care about
    * @param aPresContext the presentation context
    * @return whether aContent has aPseudoElement style attached to it
    */
   static PRBool HasPseudoStyle(nsIContent* aContent,
                                nsStyleContext* aStyleContext,
-                               nsIAtom* aPseudoElement,
+                               nsCSSPseudoElements::Type aPseudoElement,
                                nsPresContext* aPresContext)
   {
     NS_PRECONDITION(aPresContext, "Must have a prescontext");
-    NS_PRECONDITION(aPseudoElement, "Must have a pseudo name");
 
     nsRefPtr<nsStyleContext> pseudoContext;
     if (aContent) {
       pseudoContext = aPresContext->StyleSet()->
-        ProbePseudoStyleFor(aContent, aPseudoElement, aStyleContext);
+        ProbePseudoElementStyle(aContent, aPseudoElement, aStyleContext);
     }
     return pseudoContext != nsnull;
   }
 
   /**
    * If this frame is a placeholder for a float, then return the float,
    * otherwise return nsnull.  aPlaceholder must be a placeholder frame.
    */
--- a/layout/forms/nsButtonFrameRenderer.cpp
+++ b/layout/forms/nsButtonFrameRenderer.cpp
@@ -380,24 +380,26 @@ nsButtonFrameRenderer::GetAddedButtonBor
 void
 nsButtonFrameRenderer::ReResolveStyles(nsPresContext* aPresContext)
 {
   // get all the styles
   nsStyleContext* context = mFrame->GetStyleContext();
   nsStyleSet *styleSet = aPresContext->StyleSet();
 
   // style for the inner such as a dotted line (Windows)
-  mInnerFocusStyle = styleSet->ProbePseudoStyleFor(mFrame->GetContent(),
-                                                   nsCSSPseudoElements::mozFocusInner,
-                                                   context);
+  mInnerFocusStyle =
+    styleSet->ProbePseudoElementStyle(mFrame->GetContent(),
+                                      nsCSSPseudoElements::ePseudo_mozFocusInner,
+                                      context);
 
   // style for outer focus like a ridged border (MAC).
-  mOuterFocusStyle = styleSet->ProbePseudoStyleFor(mFrame->GetContent(),
-                                                   nsCSSPseudoElements::mozFocusOuter,
-                                                   context);
+  mOuterFocusStyle =
+    styleSet->ProbePseudoElementStyle(mFrame->GetContent(),
+                                      nsCSSPseudoElements::ePseudo_mozFocusOuter,
+                                      context);
 }
 
 nsStyleContext*
 nsButtonFrameRenderer::GetStyleContext(PRInt32 aIndex) const
 {
   switch (aIndex) {
   case NS_BUTTON_RENDERER_FOCUS_INNER_CONTEXT_INDEX:
     return mInnerFocusStyle;
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1157,19 +1157,18 @@ nsComboboxControlFrame::CreateFrameFor(n
   
   // Get PresShell
   nsIPresShell *shell = PresContext()->PresShell();
   nsStyleSet *styleSet = shell->StyleSet();
 
   // create the style contexts for the anonymous block frame and text frame
   nsRefPtr<nsStyleContext> styleContext;
   styleContext = styleSet->
-    ResolvePseudoStyleFor(mContent, 
-                          nsCSSAnonBoxes::mozDisplayComboboxControlFrame,
-                          mStyleContext);
+    ResolveAnonymousBoxStyle(nsCSSAnonBoxes::mozDisplayComboboxControlFrame,
+                             mStyleContext);
   if (NS_UNLIKELY(!styleContext)) {
     return nsnull;
   }
 
   nsRefPtr<nsStyleContext> textStyleContext;
   textStyleContext = styleSet->ResolveStyleForNonElement(mStyleContext);
   if (NS_UNLIKELY(!textStyleContext)) {
     return nsnull;
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -6360,34 +6360,35 @@ nsBlockFrame::SetInitialChildList(nsIAto
     // here so that RenumberLists will work (it needs the bullets to
     // store the bullet numbers).
     const nsStyleDisplay* styleDisplay = GetStyleDisplay();
     if ((nsnull == GetPrevInFlow()) &&
         (NS_STYLE_DISPLAY_LIST_ITEM == styleDisplay->mDisplay) &&
         (nsnull == mBullet)) {
       // Resolve style for the bullet frame
       const nsStyleList* styleList = GetStyleList();
-      nsIAtom *pseudoElement;
+      nsCSSPseudoElements::Type pseudoType;
       switch (styleList->mListStyleType) {
         case NS_STYLE_LIST_STYLE_DISC:
         case NS_STYLE_LIST_STYLE_CIRCLE:
         case NS_STYLE_LIST_STYLE_SQUARE:
-          pseudoElement = nsCSSPseudoElements::mozListBullet;
+          pseudoType = nsCSSPseudoElements::ePseudo_mozListBullet;
           break;
         default:
-          pseudoElement = nsCSSPseudoElements::mozListNumber;
+          pseudoType = nsCSSPseudoElements::ePseudo_mozListNumber;
           break;
       }
 
       nsIPresShell *shell = presContext->PresShell();
 
       nsStyleContext* parentStyle =
-        CorrectStyleParentFrame(this, pseudoElement)->GetStyleContext();
+        CorrectStyleParentFrame(this,
+          nsCSSPseudoElements::GetPseudoAtom(pseudoType))->GetStyleContext();
       nsRefPtr<nsStyleContext> kidSC = shell->StyleSet()->
-        ResolvePseudoStyleFor(mContent, pseudoElement, parentStyle);
+        ResolvePseudoElementStyle(mContent, pseudoType, parentStyle);
 
       // Create bullet frame
       nsBulletFrame* bullet = new (shell) nsBulletFrame(kidSC);
       if (nsnull == bullet) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
       bullet->Init(mContent, this, nsnull);
 
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -332,18 +332,19 @@ protected:
 #endif
   }
   virtual ~nsBlockFrame();
 
 #ifdef DEBUG
   already_AddRefed<nsStyleContext> GetFirstLetterStyle(nsPresContext* aPresContext)
   {
     return aPresContext->StyleSet()->
-      ProbePseudoStyleFor(mContent,
-                          nsCSSPseudoElements::firstLetter, mStyleContext);
+      ProbePseudoElementStyle(mContent,
+                              nsCSSPseudoElements::ePseudo_firstLetter,
+                              mStyleContext);
   }
 #endif
 
   /*
    * Overides member function of nsHTMLContainerFrame. Needed to handle the 
    * lines in a nsBlockFrame properly.
    */
   virtual void PaintTextDecorationLine(gfxContext* aCtx,
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -424,17 +424,17 @@ nsHTMLFramesetFrame::Init(nsIContent*   
     }
   }
 
   mNonBlankChildCount = mChildCount;
   // add blank frames for frameset cells that had no content provided
   for (int blankX = mChildCount; blankX < numCells; blankX++) {
     nsRefPtr<nsStyleContext> pseudoStyleContext;
     pseudoStyleContext = shell->StyleSet()->
-      ResolvePseudoStyleFor(nsnull, nsCSSAnonBoxes::framesetBlank, mStyleContext);
+      ResolveAnonymousBoxStyle(nsCSSAnonBoxes::framesetBlank, mStyleContext);
     if (!pseudoStyleContext) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     // XXX the blank frame is using the content of its parent - at some point it 
     // should just have null content, if we support that                                                            
     nsHTMLFramesetBlankFrame* blankFrame = new (shell) nsHTMLFramesetBlankFrame(pseudoStyleContext);
     if (!blankFrame)
@@ -1036,19 +1036,19 @@ nsHTMLFramesetFrame::Reflow(nsPresContex
     GetSizeOfChildAt(childX, size, cellIndex);
 
     if (lastRow != cellIndex.y) {  // changed to next row
       offset.x = 0;
       offset.y += lastSize.height;
       if (firstTime) { // create horizontal border
 
         nsRefPtr<nsStyleContext> pseudoStyleContext;
-        pseudoStyleContext = styleSet->ResolvePseudoStyleFor(mContent,
-                                                             nsCSSAnonBoxes::horizontalFramesetBorder,
-                                                             mStyleContext);
+        pseudoStyleContext = styleSet->
+          ResolveAnonymousBoxStyle(nsCSSAnonBoxes::horizontalFramesetBorder,
+                                   mStyleContext);
 
         borderFrame = new (shell) nsHTMLFramesetBorderFrame(pseudoStyleContext,
                                                             borderWidth,
                                                             PR_FALSE,
                                                             PR_FALSE);
         if (NS_LIKELY(borderFrame != nsnull)) {
           borderFrame->Init(mContent, this, nsnull);
           mChildCount++;
@@ -1072,19 +1072,19 @@ nsHTMLFramesetFrame::Reflow(nsPresContex
       }
       offset.y += borderWidth;
     } else {
       if (cellIndex.x > 0) {  // moved to next col in same row
         if (0 == cellIndex.y) { // in 1st row
           if (firstTime) { // create vertical border
             
             nsRefPtr<nsStyleContext> pseudoStyleContext;
-            pseudoStyleContext = styleSet->ResolvePseudoStyleFor(mContent,
-                                                                 nsCSSAnonBoxes::verticalFramesetBorder,
-                                                                 mStyleContext);
+            pseudoStyleContext = styleSet->
+              ResolveAnonymousBoxStyle(nsCSSAnonBoxes::verticalFramesetBorder,
+                                       mStyleContext);
 
             borderFrame = new (shell) nsHTMLFramesetBorderFrame(pseudoStyleContext, 
                                                                 borderWidth,
                                                                 PR_TRUE,
                                                                 PR_FALSE);
             if (NS_LIKELY(borderFrame != nsnull)) {
               borderFrame->Init(mContent, this, nsnull);
               mChildCount++;
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -1052,18 +1052,17 @@ nsFirstLineFrame::Reflow(nsPresContext* 
       nsStyleContext* parentContext = first->GetParent()->GetStyleContext();
       if (parentContext) {
         // Create a new style context that is a child of the parent
         // style context thus removing the :first-line style. This way
         // we behave as if an anonymous (unstyled) span was the child
         // of the parent frame.
         nsRefPtr<nsStyleContext> newSC;
         newSC = aPresContext->StyleSet()->
-          ResolvePseudoStyleFor(nsnull,
-                                nsCSSAnonBoxes::mozLineFrame, parentContext);
+          ResolveAnonymousBoxStyle(nsCSSAnonBoxes::mozLineFrame, parentContext);
         if (newSC) {
           // Switch to the new style context.
           SetStyleContext(newSC);
 
           // Re-resolve all children
           ReParentChildListStyle(aPresContext, mFrames, this);
         }
       }
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -3157,18 +3157,19 @@ nsTextPaintStyle::InitSelectionColors()
 
   nsIFrame* nonGeneratedAncestor = nsLayoutUtils::GetNonGeneratedAncestor(mFrame);
   nsIContent* selectionContent = FindElementAncestor(nonGeneratedAncestor->GetContent());
 
   if (selectionContent &&
       selectionStatus == nsISelectionController::SELECTION_ON) {
     nsRefPtr<nsStyleContext> sc = nsnull;
     sc = mPresContext->StyleSet()->
-      ProbePseudoStyleFor(selectionContent, nsCSSPseudoElements::mozSelection,
-                          mFrame->GetStyleContext());
+      ProbePseudoElementStyle(selectionContent,
+                              nsCSSPseudoElements::ePseudo_mozSelection,
+                              mFrame->GetStyleContext());
     // Use -moz-selection pseudo class.
     if (sc) {
       const nsStyleBackground* bg = sc->GetStyleBackground();
       mSelectionBGColor = bg->mBackgroundColor;
       mSelectionTextColor = sc->GetStyleColor()->mColor;
       return PR_TRUE;
     }
   }
--- a/layout/mathml/mathml.css
+++ b/layout/mathml/mathml.css
@@ -400,18 +400,21 @@ mtd[-moz-math-columnline="dashed"] {
    clicking the pref to override document fonts.
 /**************************************************************************/
 
 ::-moz-math-stretchy {
   font-style: normal;
   font-family: serif; /* an empty family is ignored as an error and behaves like inherit */
 /*  background-color: #3C6; */
 }
+/* Don't actually style -moz-math-anonymous by default */
+/*
 ::-moz-math-anonymous {
 }
+*/
 
 /**********************************************************************/
 /* Hide embedded semantic MathML content (as opposed to presentational
    content, which we render). Ideally, here is the behavior that we want:
 
    if there is an annotation-xml[encoding="MathML-Presentation"]
      render that annotation, and ignore the first child of the
      <semantics> element and all other annotations, 
--- a/layout/mathml/nsMathMLFrame.cpp
+++ b/layout/mathml/nsMathMLFrame.cpp
@@ -34,17 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsINameSpaceManager.h"
 #include "nsMathMLFrame.h"
 #include "nsMathMLChar.h"
-#include "nsCSSAnonBoxes.h"
+#include "nsCSSPseudoElements.h"
 
 // used to map attributes into CSS rules
 #include "nsIDocument.h"
 #include "nsStyleSet.h"
 #include "nsIStyleSheet.h"
 #include "nsICSSStyleSheet.h"
 #include "nsIDOMCSSStyleSheet.h"
 #include "nsICSSRule.h"
@@ -159,22 +159,22 @@ nsMathMLFrame::UpdatePresentationData(PR
 // the Style System via the Get/Set AdditionalStyleContext() APIs.
 /* static */ void
 nsMathMLFrame::ResolveMathMLCharStyle(nsPresContext*  aPresContext,
                                       nsIContent*      aContent,
                                       nsStyleContext*  aParentStyleContext,
                                       nsMathMLChar*    aMathMLChar,
                                       PRBool           aIsMutableChar)
 {
-  nsIAtom* pseudoStyle = (aIsMutableChar) ?
-    nsCSSAnonBoxes::mozMathStretchy :
-    nsCSSAnonBoxes::mozMathAnonymous; // savings
+  nsCSSPseudoElements::Type pseudoType = (aIsMutableChar) ?
+    nsCSSPseudoElements::ePseudo_mozMathStretchy :
+    nsCSSPseudoElements::ePseudo_mozMathAnonymous; // savings
   nsRefPtr<nsStyleContext> newStyleContext;
   newStyleContext = aPresContext->StyleSet()->
-    ResolvePseudoStyleFor(aContent, pseudoStyle, aParentStyleContext);
+    ResolvePseudoElementStyle(aContent, pseudoType, aParentStyleContext);
 
   if (newStyleContext)
     aMathMLChar->SetStyleContext(newStyleContext);
 }
 
 /* static */ void
 nsMathMLFrame::GetEmbellishDataFrom(nsIFrame*        aFrame,
                                     nsEmbellishData& aEmbellishData)
--- a/layout/style/nsCSSPseudoElements.cpp
+++ b/layout/style/nsCSSPseudoElements.cpp
@@ -117,16 +117,24 @@ nsCSSPseudoElements::GetPseudoType(nsIAt
 #endif
 
     return ePseudo_AnonBox;
   }
 
   return ePseudo_NotPseudoElement;
 }
 
+/* static */ nsIAtom*
+nsCSSPseudoElements::GetPseudoAtom(Type aType)
+{
+  NS_ASSERTION(aType < nsCSSPseudoElements::ePseudo_PseudoElementCount,
+               "Unexpected type");
+  return *CSSPseudoElements_info[aType].mAtom;
+}
+
 /* static */ PRUint32
 nsCSSPseudoElements::FlagsForPseudoElement(nsIAtom *aAtom)
 {
   PRUint32 i;
   for (i = 0; i < NS_ARRAY_LENGTH(CSSPseudoElements_info); ++i) {
     if (*CSSPseudoElements_info[i].mAtom == aAtom) {
       break;
     }
--- a/layout/style/nsCSSPseudoElements.h
+++ b/layout/style/nsCSSPseudoElements.h
@@ -82,26 +82,29 @@ public:
   enum Type {
     // If the actual pseudo-elements stop being first here, change
     // GetPseudoType.
 #define CSS_PSEUDO_ELEMENT(_name, _value_, _flags) \
     ePseudo_##_name,
 #include "nsCSSPseudoElementList.h"
 #undef CSS_PSEUDO_ELEMENT
     ePseudo_PseudoElementCount,
-    ePseudo_NotPseudoElement = ePseudo_PseudoElementCount,
-    ePseudo_AnonBox,
+    ePseudo_AnonBox = ePseudo_PseudoElementCount,
 #ifdef MOZ_XUL
     ePseudo_XULTree,
 #endif
+    ePseudo_NotPseudoElement,
     ePseudo_MAX
   };
 
   static Type GetPseudoType(nsIAtom* aAtom);
 
+  // Get the atom for a given Type.  aType must be < ePseudo_PseudoElementCount
+  static nsIAtom* GetPseudoAtom(Type aType);
+
 private:
   static PRUint32 FlagsForPseudoElement(nsIAtom *aAtom);
 
   // Does the given pseudo-element have all of the flags given?
   static PRBool PseudoElementHasFlags(nsIAtom *aAtom, PRUint32 aFlags)
   {
     return (FlagsForPseudoElement(aAtom) & aFlags) == aFlags;
   }
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -320,27 +320,26 @@ nsComputedDOMStyle::GetPropertyValue(con
 /* static */
 already_AddRefed<nsStyleContext>
 nsComputedDOMStyle::GetStyleContextForContent(nsIContent* aContent,
                                               nsIAtom* aPseudo,
                                               nsIPresShell* aPresShell)
 {
   NS_ASSERTION(aContent->IsNodeOfType(nsINode::eELEMENT),
                "aContent must be an element");
-  if (!aPseudo) {
-    // If there's no pres shell, get it from the content
-    if (!aPresShell) {
-      aPresShell = GetPresShellForContent(aContent);
-      if (!aPresShell)
-        return nsnull;
-    }
-
-    aPresShell->FlushPendingNotifications(Flush_Style);
+
+  // If there's no pres shell, get it from the content
+  if (!aPresShell) {
+    aPresShell = GetPresShellForContent(aContent);
+    if (!aPresShell)
+      return nsnull;
   }
 
+  aPresShell->FlushPendingNotifications(Flush_Style);
+
   return GetStyleContextForContentNoFlush(aContent, aPseudo, aPresShell);
 }
 
 /* static */
 already_AddRefed<nsStyleContext>
 nsComputedDOMStyle::GetStyleContextForContentNoFlush(nsIContent* aContent,
                                                      nsIAtom* aPseudo,
                                                      nsIPresShell* aPresShell)
@@ -371,26 +370,30 @@ nsComputedDOMStyle::GetStyleContextForCo
   }
 
   // No frame has been created or we have a pseudo, so resolve the
   // style ourselves
   nsRefPtr<nsStyleContext> parentContext;
   nsIContent* parent = aPseudo ? aContent : aContent->GetParent();
   // Don't resolve parent context for document fragments.
   if (parent && parent->IsNodeOfType(nsINode::eELEMENT))
-    parentContext = GetStyleContextForContent(parent, nsnull, aPresShell);
+    parentContext = GetStyleContextForContentNoFlush(parent, nsnull, aPresShell);
 
   nsPresContext *presContext = aPresShell->GetPresContext();
   if (!presContext)
     return nsnull;
 
   nsStyleSet *styleSet = aPresShell->StyleSet();
 
   if (aPseudo) {
-    return styleSet->ResolvePseudoStyleFor(aContent, aPseudo, parentContext);
+    nsCSSPseudoElements::Type type = nsCSSPseudoElements::GetPseudoType(aPseudo);
+    if (type >= nsCSSPseudoElements::ePseudo_PseudoElementCount) {
+      return nsnull;
+    }
+    return styleSet->ResolvePseudoElementStyle(aContent, type, parentContext);
   }
 
   return styleSet->ResolveStyleFor(aContent, parentContext);
 }
 
 /* static */
 nsIPresShell*
 nsComputedDOMStyle::GetPresShellForContent(nsIContent* aContent)
--- a/layout/style/nsStyleAnimation.cpp
+++ b/layout/style/nsStyleAnimation.cpp
@@ -811,16 +811,17 @@ StyleWithDeclarationAdded(nsCSSProperty 
   }
 
   // Create a temporary nsStyleContext for the style rule
   nsCOMArray<nsIStyleRule> ruleArray;
   ruleArray.AppendObject(styleRule);
   nsStyleSet* styleSet = styleContext->PresContext()->StyleSet();
   return styleSet->ResolveStyleForRules(styleContext->GetParent(),
                                         styleContext->GetPseudo(),
+                                        styleContext->GetPseudoType(),
                                         styleContext->GetRuleNode(),
                                         ruleArray);
 }
 
 PRBool
 nsStyleAnimation::ComputeValue(nsCSSProperty aProperty,
                                nsIContent* aTargetElement,
                                const nsAString& aSpecifiedValue,
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -45,36 +45,41 @@
 #include "nsIStyleRule.h"
 
 #include "nsCOMPtr.h"
 #include "nsStyleSet.h"
 #include "nsIPresShell.h"
 
 #include "nsRuleNode.h"
 #include "nsStyleContext.h"
+#include "prlog.h"
 
 #ifdef DEBUG
 // #define NOISY_DEBUG
 #endif
 
 //----------------------------------------------------------------------
 
 
 nsStyleContext::nsStyleContext(nsStyleContext* aParent,
                                nsIAtom* aPseudoTag,
+                               nsCSSPseudoElements::Type aPseudoType,
                                nsRuleNode* aRuleNode,
                                nsPresContext* aPresContext)
   : mParent(aParent),
     mChild(nsnull),
     mEmptyChild(nsnull),
     mPseudoTag(aPseudoTag),
     mRuleNode(aRuleNode),
-    mBits(0),
+    mBits(((PRUint32)aPseudoType) << NS_STYLE_CONTEXT_TYPE_SHIFT),
     mRefCnt(0)
 {
+  PR_STATIC_ASSERT((PR_UINT32_MAX >> NS_STYLE_CONTEXT_TYPE_SHIFT) >
+                   nsCSSPseudoElements::ePseudo_MAX);
+
   mNextSibling = this;
   mPrevSibling = this;
   if (mParent) {
     mParent->AddRef();
     mParent->AddChild(this);
 #ifdef DEBUG
     nsRuleNode *r1 = mParent->GetRuleNode(), *r2 = aRuleNode;
     while (r1->GetParent())
@@ -567,18 +572,20 @@ nsStyleContext::Destroy()
   // Don't let the memory be freed, since it will be recycled
   // instead. Don't call the global operator delete.
   presContext->FreeToShell(sizeof(nsStyleContext), this);
 }
 
 already_AddRefed<nsStyleContext>
 NS_NewStyleContext(nsStyleContext* aParentContext,
                    nsIAtom* aPseudoTag,
+                   nsCSSPseudoElements::Type aPseudoType,
                    nsRuleNode* aRuleNode,
                    nsPresContext* aPresContext)
 {
-  nsStyleContext* context = new (aPresContext) nsStyleContext(aParentContext, aPseudoTag, 
-                                                              aRuleNode, aPresContext);
+  nsStyleContext* context =
+    new (aPresContext) nsStyleContext(aParentContext, aPseudoTag, aPseudoType,
+                                      aRuleNode, aPresContext);
   if (context)
     context->AddRef();
   return context;
 }
 
--- a/layout/style/nsStyleContext.h
+++ b/layout/style/nsStyleContext.h
@@ -39,16 +39,17 @@
 
 /* the interface (to internal code) for retrieving computed style data */
 
 #ifndef _nsStyleContext_h_
 #define _nsStyleContext_h_
 
 #include "nsRuleNode.h"
 #include "nsIAtom.h"
+#include "nsCSSPseudoElements.h"
 
 class nsPresContext;
 
 /**
  * An nsStyleContext represents the computed style data for an element.
  * The computed style data are stored in a set of structs (see
  * nsStyleStruct.h) that are cached either on the style context or in
  * the rule tree (see nsRuleNode.h for a description of this caching and
@@ -67,17 +68,18 @@ class nsPresContext;
  *     expectation, but it makes sense in this case)
  * Style contexts participate in the mark phase of rule node garbage
  * collection.
  */
 
 class nsStyleContext
 {
 public:
-  nsStyleContext(nsStyleContext* aParent, nsIAtom* aPseudoTag, 
+  nsStyleContext(nsStyleContext* aParent, nsIAtom* aPseudoTag,
+                 nsCSSPseudoElements::Type aPseudoType,
                  nsRuleNode* aRuleNode, nsPresContext* aPresContext) NS_HIDDEN;
   ~nsStyleContext() NS_HIDDEN;
 
   NS_HIDDEN_(void*) operator new(size_t sz, nsPresContext* aPresContext) CPP_THROW_NEW;
   NS_HIDDEN_(void) Destroy();
 
   nsrefcnt AddRef() {
     if (mRefCnt == PR_UINT32_MAX) {
@@ -103,16 +105,20 @@ public:
     return mRefCnt;
   }
 
   nsPresContext* PresContext() const { return mRuleNode->GetPresContext(); }
 
   nsStyleContext* GetParent() const { return mParent; }
 
   nsIAtom* GetPseudo() const { return mPseudoTag; }
+  nsCSSPseudoElements::Type GetPseudoType() const {
+    return static_cast<nsCSSPseudoElements::Type>(mBits >>
+                                                  NS_STYLE_CONTEXT_TYPE_SHIFT);
+  }
 
   NS_HIDDEN_(already_AddRefed<nsStyleContext>)
   FindChildWithRules(const nsIAtom* aPseudoTag, nsRuleNode* aRules);
 
   // Does this style context or any of its ancestors have text
   // decorations?
   PRBool HasTextDecorations() const
     { return !!(mBits & NS_STYLE_HAS_TEXT_DECORATIONS); }
@@ -217,11 +223,12 @@ protected:
   PRUint32                mBits; // Which structs are inherited from the
                                  // parent context.
   PRUint32                mRefCnt;
 };
 
 NS_HIDDEN_(already_AddRefed<nsStyleContext>)
 NS_NewStyleContext(nsStyleContext* aParentContext,
                    nsIAtom* aPseudoTag,
+                   nsCSSPseudoElements::Type aPseudoType,
                    nsRuleNode* aRuleNode,
                    nsPresContext* aPresContext);
 #endif
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -426,36 +426,49 @@ EnumRulesMatching(nsIStyleRuleProcessor*
  * on the rule nodes) between siblings and cousins of the same
  * generation.  (It works for cousins of the same generation since
  * |aParentContext| could itself be a shared context.)
  */
 already_AddRefed<nsStyleContext>
 nsStyleSet::GetContext(nsPresContext* aPresContext, 
                        nsStyleContext* aParentContext, 
                        nsRuleNode* aRuleNode,
-                       nsIAtom* aPseudoTag)
+                       nsIAtom* aPseudoTag,
+                       nsCSSPseudoElements::Type aPseudoType)
 {
+  NS_PRECONDITION((!aPseudoTag &&
+                   aPseudoType ==
+                     nsCSSPseudoElements::ePseudo_NotPseudoElement) ||
+                  (aPseudoTag &&
+                   nsCSSPseudoElements::GetPseudoType(aPseudoTag) ==
+                     aPseudoType),
+                  "Pseudo mismatch");
+
   nsStyleContext* result = nsnull;
       
   if (aParentContext)
     result = aParentContext->FindChildWithRules(aPseudoTag, aRuleNode).get();
 
 #ifdef NOISY_DEBUG
   if (result)
     fprintf(stdout, "--- SharedSC %d ---\n", ++gSharedCount);
   else
     fprintf(stdout, "+++ NewSC %d +++\n", ++gNewCount);
 #endif
 
   if (!result) {
-    result = NS_NewStyleContext(aParentContext, aPseudoTag, aRuleNode,
-                                aPresContext).get();
+    result = NS_NewStyleContext(aParentContext, aPseudoTag, aPseudoType,
+                                aRuleNode, aPresContext).get();
     if (!aParentContext && result)
       mRoots.AppendElement(result);
   }
+  else {
+    NS_ASSERTION(result->GetPseudoType() == aPseudoType, "Unexpected type");
+    NS_ASSERTION(result->GetPseudo() == aPseudoTag, "Unexpected pseudo");
+  }
 
   return result;
 }
 
 void
 nsStyleSet::AddImportantRules(nsRuleNode* aCurrLevelNode,
                               nsRuleNode* aLastPrevLevelNode,
                               nsRuleWalker* aRuleWalker)
@@ -730,25 +743,27 @@ nsStyleSet::ResolveStyleFor(nsIContent* 
   NS_ASSERTION(aContent->IsNodeOfType(nsINode::eELEMENT),
                "content must be element");
 
   if (aContent && presContext) {
     nsRuleWalker ruleWalker(mRuleTree);
     ElementRuleProcessorData data(presContext, aContent, &ruleWalker);
     FileRules(EnumRulesMatching, &data, &ruleWalker);
     result = GetContext(presContext, aParentContext,
-                        ruleWalker.GetCurrentNode(), nsnull).get();
+                        ruleWalker.GetCurrentNode(), nsnull,
+                        nsCSSPseudoElements::ePseudo_NotPseudoElement).get();
   }
 
   return result;
 }
 
 already_AddRefed<nsStyleContext>
 nsStyleSet::ResolveStyleForRules(nsStyleContext* aParentContext,
                                  nsIAtom* aPseudoTag,
+                                 nsCSSPseudoElements::Type aPseudoType,
                                  nsRuleNode *aRuleNode,
                                  const nsCOMArray<nsIStyleRule> &aRules)
 {
   NS_ENSURE_FALSE(mInShutdown, nsnull);
   nsStyleContext* result = nsnull;
   nsPresContext *presContext = PresContext();
 
   if (presContext) {
@@ -757,30 +772,32 @@ nsStyleSet::ResolveStyleForRules(nsStyle
       ruleWalker.SetCurrentNode(aRuleNode);
     // FIXME: Perhaps this should be passed in, but it probably doesn't
     // matter.
     ruleWalker.SetLevel(eDocSheet, PR_FALSE, PR_FALSE);
     for (PRInt32 i = 0; i < aRules.Count(); i++) {
       ruleWalker.Forward(aRules.ObjectAt(i));
     }
     result = GetContext(presContext, aParentContext,
-                        ruleWalker.GetCurrentNode(), aPseudoTag).get();
+                        ruleWalker.GetCurrentNode(), aPseudoTag,
+                        aPseudoType).get();
   }
   return result;
 }
 
 already_AddRefed<nsStyleContext>
 nsStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext)
 {
   nsStyleContext* result = nsnull;
   nsPresContext *presContext = PresContext();
 
   if (presContext) {
     result = GetContext(presContext, aParentContext, mRuleTree,
-                        nsCSSAnonBoxes::mozNonElement).get();
+                        nsCSSAnonBoxes::mozNonElement,
+                        nsCSSPseudoElements::ePseudo_AnonBox).get();
   }
 
   return result;
 }
 
 void
 nsStyleSet::WalkRestrictionRule(nsIAtom* aPseudoType,
                                 nsRuleWalker* aRuleWalker)
@@ -803,16 +820,17 @@ EnumPseudoRulesMatching(nsIStyleRuleProc
 
   aProcessor->RulesMatching(data);
   return PR_TRUE;
 }
 
 already_AddRefed<nsStyleContext>
 nsStyleSet::ResolvePseudoStyleFor(nsIContent* aParentContent,
                                   nsIAtom* aPseudoTag,
+                                  nsCSSPseudoElements::Type aPseudoType,
                                   nsStyleContext* aParentContext,
                                   nsICSSPseudoComparator* aComparator)
 {
   NS_ENSURE_FALSE(mInShutdown, nsnull);
 
   nsStyleContext*  result = nsnull;
   nsPresContext *presContext = PresContext();
 
@@ -821,75 +839,72 @@ nsStyleSet::ResolvePseudoStyleFor(nsICon
                aParentContent->IsNodeOfType(nsINode::eELEMENT),
                "content (if non-null) must be element");
   NS_ASSERTION(aParentContent ||
                nsCSSAnonBoxes::IsAnonBox(aPseudoTag),
                "null content must correspond to anonymous box");
   NS_ASSERTION(nsCSSAnonBoxes::IsAnonBox(aPseudoTag) ||
                nsCSSPseudoElements::IsPseudoElement(aPseudoTag),
                "aPseudoTag must be pseudo-element or anonymous box");
+  NS_ASSERTION(nsCSSPseudoElements::GetPseudoType(aPseudoTag) == aPseudoType,
+               "Incorrect pseudo type");
 
   if (aPseudoTag && presContext) {
     nsRuleWalker ruleWalker(mRuleTree);
     PseudoRuleProcessorData data(presContext, aParentContent, aPseudoTag,
                                  aComparator, &ruleWalker);
     WalkRestrictionRule(aPseudoTag, &ruleWalker);
     FileRules(EnumPseudoRulesMatching, &data, &ruleWalker);
 
     result = GetContext(presContext, aParentContext,
-                        ruleWalker.GetCurrentNode(), aPseudoTag).get();
+                        ruleWalker.GetCurrentNode(), aPseudoTag,
+                        aPseudoType).get();
   }
 
   return result;
 }
 
 already_AddRefed<nsStyleContext>
-nsStyleSet::ProbePseudoStyleFor(nsIContent* aParentContent,
-                                nsIAtom* aPseudoTag,
-                                nsStyleContext* aParentContext)
+nsStyleSet::ProbePseudoElementStyle(nsIContent* aParentContent,
+                                    nsCSSPseudoElements::Type aType,
+                                    nsStyleContext* aParentContext)
 {
   NS_ENSURE_FALSE(mInShutdown, nsnull);
   
+  nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
+
   nsStyleContext*  result = nsnull;
   nsPresContext *presContext = PresContext();
 
-  NS_ASSERTION(aPseudoTag, "must have pseudo tag");
+  NS_ASSERTION(pseudoTag, "must have pseudo tag");
   NS_ASSERTION(aParentContent &&
                aParentContent->IsNodeOfType(nsINode::eELEMENT),
                "aParentContent must be element");
-  //NS_ASSERTION(nsCSSPseudoElements::IsPseudoElement(aPseudoTag),
-  //             "aPseudoTag must be a pseudo-element");
-  NS_ASSERTION(aParentContent ||
-               nsCSSAnonBoxes::IsAnonBox(aPseudoTag),
-               "null content must correspond to anonymous box");
-  NS_ASSERTION(nsCSSAnonBoxes::IsAnonBox(aPseudoTag) ||
-               nsCSSPseudoElements::IsPseudoElement(aPseudoTag),
-               "aPseudoTag must be pseudo-element or anonymous box");
 
-  if (aPseudoTag && presContext) {
+  if (presContext) {
     nsRuleWalker ruleWalker(mRuleTree);
-    PseudoRuleProcessorData data(presContext, aParentContent, aPseudoTag,
+    PseudoRuleProcessorData data(presContext, aParentContent, pseudoTag,
                                  nsnull, &ruleWalker);
-    WalkRestrictionRule(aPseudoTag, &ruleWalker);
+    WalkRestrictionRule(pseudoTag, &ruleWalker);
     // not the root if there was a restriction rule
     nsRuleNode *adjustedRoot = ruleWalker.GetCurrentNode();
     FileRules(EnumPseudoRulesMatching, &data, &ruleWalker);
 
     nsRuleNode *ruleNode = ruleWalker.GetCurrentNode();
     if (ruleNode != adjustedRoot)
       result =
-        GetContext(presContext, aParentContext, ruleNode, aPseudoTag).get();
+        GetContext(presContext, aParentContext, ruleNode, pseudoTag, aType).get();
   }
 
   // For :before and :after pseudo-elements, having display: none or no
   // 'content' property is equivalent to not having the pseudo-element
   // at all.
   if (result &&
-      (aPseudoTag == nsCSSPseudoElements::before ||
-       aPseudoTag == nsCSSPseudoElements::after)) {
+      (pseudoTag == nsCSSPseudoElements::before ||
+       pseudoTag == nsCSSPseudoElements::after)) {
     const nsStyleDisplay *display = result->GetStyleDisplay();
     const nsStyleContent *content = result->GetStyleContent();
     // XXXldb What is contentCount for |content: ""|?
     if (display->mDisplay == NS_STYLE_DISPLAY_NONE ||
         content->ContentCount() == 0) {
       result->Release();
       result = nsnull;
     }
@@ -1003,20 +1018,22 @@ nsStyleSet::ReParentStyleContext(nsPresC
 
   if (aPresContext && aStyleContext) {
     if (aStyleContext->GetParent() == aNewParentContext) {
       aStyleContext->AddRef();
       return aStyleContext;
     }
     else {  // really a new parent
       nsIAtom* pseudoTag = aStyleContext->GetPseudo();
+      nsCSSPseudoElements::Type pseudoType = aStyleContext->GetPseudoType();
       nsRuleNode* ruleNode = aStyleContext->GetRuleNode();
 
       already_AddRefed<nsStyleContext> result =
-          GetContext(aPresContext, aNewParentContext, ruleNode, pseudoTag);
+        GetContext(aPresContext, aNewParentContext, ruleNode, pseudoTag,
+                   pseudoType);
       return result;
     }
   }
   return nsnull;
 }
 
 struct StatefulData : public StateRuleProcessorData {
   StatefulData(nsPresContext* aPresContext,
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -50,16 +50,18 @@
 #include "nsIStyleRuleProcessor.h"
 #include "nsICSSStyleSheet.h"
 #include "nsBindingManager.h"
 #include "nsRuleNode.h"
 #include "nsTArray.h"
 #include "nsCOMArray.h"
 #include "nsAutoPtr.h"
 #include "nsIStyleRule.h"
+#include "nsCSSPseudoElements.h"
+#include "nsCSSAnonBoxes.h"
 
 class nsIURI;
 class nsCSSFontFaceRule;
 class nsRuleWalker;
 struct RuleProcessorData;
 
 class nsEmptyStyleRule : public nsIStyleRule
 {
@@ -92,55 +94,106 @@ class nsStyleSet
 
   // enable / disable the Quirk style sheet
   void EnableQuirkStyleSheet(PRBool aEnable);
 
   // get a style context for a non-pseudo frame.
   already_AddRefed<nsStyleContext>
   ResolveStyleFor(nsIContent* aContent, nsStyleContext* aParentContext);
 
-  // Get a style context (with the given parent and pseudo-tag) for a
+  // Get a style context (with the given parent and pseudo-tag/type) for a
   // sequence of style rules consisting of the concatenation of:
   //  (1) the rule sequence represented by aRuleNode (which is the empty
   //      sequence if aRuleNode is null or the root of the rule tree), and
   //  (2) the rules in the |aRules| array.
   already_AddRefed<nsStyleContext>
   ResolveStyleForRules(nsStyleContext* aParentContext,
                        nsIAtom* aPseudoTag,
+                       nsCSSPseudoElements::Type aPseudoType,
                        nsRuleNode *aRuleNode,
                        const nsCOMArray<nsIStyleRule> &aRules);
 
   // Get a style context for a non-element (which no rules will match),
   // such as text nodes, placeholder frames, and the nsFirstLetterFrame
   // for everything after the first letter.
   //
   // Perhaps this should go away and we shouldn't even create style
   // contexts for such content nodes.  However, not doing any rule
   // matching for them is a first step.
   already_AddRefed<nsStyleContext>
   ResolveStyleForNonElement(nsStyleContext* aParentContext);
 
+  // Get a style context for a pseudo-element.  aParentContent must be
+  // non-null.  aPseudoID is the nsCSSPseudoElements::Type for the
+  // pseudo-element.
+  already_AddRefed<nsStyleContext>
+  ResolvePseudoElementStyle(nsIContent* aParentContent,
+                            nsCSSPseudoElements::Type aType,
+                            nsStyleContext* aParentContext) {
+    return ResolvePseudoStyleFor(aParentContent,
+                                 nsCSSPseudoElements::GetPseudoAtom(aType),
+                                 aType,
+                                 aParentContext);
+  }
+
+  // This functions just like ResolvePseudoElementStyle except that it will
+  // return nsnull if there are no explicit style rules for that
+  // pseudo element.
+  already_AddRefed<nsStyleContext>
+  ProbePseudoElementStyle(nsIContent* aParentContent,
+                          nsCSSPseudoElements::Type aType,
+                          nsStyleContext* aParentContext);
+  
+  // Get a style context for an anonymous box.  aPseudoTag is the
+  // pseudo-tag to use and must be non-null.
+  already_AddRefed<nsStyleContext>
+  ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag,
+                           nsStyleContext* aParentContext) {
+#ifdef DEBUG
+    PRBool isAnonBox = nsCSSAnonBoxes::IsAnonBox(aPseudoTag)
+#ifdef MOZ_XUL
+                 && !nsCSSAnonBoxes::IsTreePseudoElement(aPseudoTag)
+#endif
+      ;
+    NS_PRECONDITION(isAnonBox, "Unexpected pseudo");
+#endif
+    return ResolvePseudoStyleFor(nsnull, aPseudoTag,
+                                 nsCSSPseudoElements::ePseudo_AnonBox,
+                                 aParentContext);
+  }
+
+#ifdef MOZ_XUL
+  // Get a style context for a XUL tree pseudo.  aPseudoTag is the
+  // pseudo-tag to use and must be non-null.  aParentContent must be
+  // non-null.  aComparator must be non-null.
+  already_AddRefed<nsStyleContext>
+  ResolveXULTreePseudoStyle(nsIContent* aParentContent,
+                            nsIAtom* aPseudoTag,
+                            nsStyleContext* aParentContext,
+                            nsICSSPseudoComparator* aComparator) {
+    NS_PRECONDITION(nsCSSAnonBoxes::IsTreePseudoElement(aPseudoTag),
+                    "Unexpected pseudo");
+    return ResolvePseudoStyleFor(aParentContent, aPseudoTag,
+                                 nsCSSPseudoElements::ePseudo_XULTree,
+                                 aParentContext, aComparator);
+  }
+#endif
+
+private:
   // get a style context for a pseudo-element (i.e.,
   // |aPseudoTag == nsCOMPtr<nsIAtom>(do_GetAtom(":first-line"))|, in
   // which case aParentContent must be non-null, or an anonymous box, in
   // which case it may be null or non-null.
   already_AddRefed<nsStyleContext>
   ResolvePseudoStyleFor(nsIContent* aParentContent,
                         nsIAtom* aPseudoTag,
+                        nsCSSPseudoElements::Type aPseudoType,
                         nsStyleContext* aParentContext,
                         nsICSSPseudoComparator* aComparator = nsnull);
-
-  // This functions just like ResolvePseudoStyleFor except that it will
-  // return nsnull if there are no explicit style rules for that
-  // pseudo element.  It should be used only for pseudo-elements.
-  already_AddRefed<nsStyleContext>
-  ProbePseudoStyleFor(nsIContent* aParentContent,
-                      nsIAtom* aPseudoTag,
-                      nsStyleContext* aParentContext);
-
+public:
   // Append all the currently-active font face rules to aArray.  Return
   // true for success and false for failure.
   PRBool AppendFontFaceRules(nsPresContext* aPresContext,
                              nsTArray<nsFontFaceRuleContainer>& aArray);
 
   // Begin ignoring style context destruction, to avoid lots of unnecessary
   // work on document teardown.
   void BeginShutdown(nsPresContext* aPresContext);
@@ -306,17 +359,18 @@ class nsStyleSet
   // Enumerate all the rules in a way that doesn't care about the order
   // of the rules and break out if the enumeration is halted.
   void WalkRuleProcessors(nsIStyleRuleProcessor::EnumFunc aFunc,
                           RuleProcessorData* aData);
 
   already_AddRefed<nsStyleContext> GetContext(nsPresContext* aPresContext,
                                               nsStyleContext* aParentContext,
                                               nsRuleNode* aRuleNode,
-                                              nsIAtom* aPseudoTag);
+                                              nsIAtom* aPseudoTag,
+                                              nsCSSPseudoElements::Type aPseudoType);
 
   nsPresContext* PresContext() { return mRuleTree->GetPresContext(); }
 
   // The sheets in each array in mSheets are stored with the most significant
   // sheet last.
   nsCOMArray<nsIStyleSheet> mSheets[eSheetTypeCount];
 
   nsCOMPtr<nsIStyleRuleProcessor> mRuleProcessors[eSheetTypeCount];
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -78,16 +78,19 @@ class imgIContainer;
 // NS_STYLE_INHERIT_BIT defined in nsStyleStructFwd.h
 #define NS_STYLE_INHERIT_MASK             0x00ffffff
 
 // Additional bits for nsStyleContext's mBits:
 // See nsStyleContext::HasTextDecorations
 #define NS_STYLE_HAS_TEXT_DECORATIONS     0x01000000
 // See nsStyleContext::HasPseudoElementData.
 #define NS_STYLE_HAS_PSEUDO_ELEMENT_DATA  0x02000000
+// See nsStyleContext::GetPseudoEnum
+#define NS_STYLE_CONTEXT_TYPE_MASK        0xf0000000
+#define NS_STYLE_CONTEXT_TYPE_SHIFT       28
 
 // Additional bits for nsRuleNode's mDependentBits:
 #define NS_RULE_NODE_GC_MARK              0x02000000
 #define NS_RULE_NODE_IS_IMPORTANT         0x08000000
 #define NS_RULE_NODE_LEVEL_MASK           0xf0000000
 #define NS_RULE_NODE_LEVEL_SHIFT          28
 
 // The lifetime of these objects is managed by the presshell's arena.
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -663,19 +663,18 @@ nsTableCellMap* nsTableFrame::GetCellMap
 nsTableColGroupFrame*
 nsTableFrame::CreateAnonymousColGroupFrame(nsTableColGroupType aColGroupType)
 {
   nsIContent* colGroupContent = GetContent();
   nsPresContext* presContext = PresContext();
   nsIPresShell *shell = presContext->PresShell();
 
   nsRefPtr<nsStyleContext> colGroupStyle;
-  colGroupStyle = shell->StyleSet()->ResolvePseudoStyleFor(colGroupContent,
-                                                           nsCSSAnonBoxes::tableColGroup,
-                                                           mStyleContext);
+  colGroupStyle = shell->StyleSet()->
+    ResolveAnonymousBoxStyle(nsCSSAnonBoxes::tableColGroup, mStyleContext);
   // Create a col group frame
   nsIFrame* newFrame = NS_NewTableColGroupFrame(shell, colGroupStyle);
   if (newFrame) {
     ((nsTableColGroupFrame *)newFrame)->SetColType(aColGroupType);
     newFrame->Init(colGroupContent, this, nsnull);
   }
   return (nsTableColGroupFrame *)newFrame;
 }
@@ -728,19 +727,18 @@ nsTableFrame::AppendAnonymousColFrames(n
     nsIContent* iContent;
     nsRefPtr<nsStyleContext> styleContext;
     nsStyleContext* parentStyleContext;
 
     // all anonymous cols that we create here use a pseudo style context of the
     // col group
     iContent = aColGroupFrame->GetContent();
     parentStyleContext = aColGroupFrame->GetStyleContext();
-    styleContext = shell->StyleSet()->ResolvePseudoStyleFor(iContent,
-                                                            nsCSSAnonBoxes::tableCol,
-                                                            parentStyleContext);
+    styleContext = shell->StyleSet()->
+      ResolveAnonymousBoxStyle(nsCSSAnonBoxes::tableCol, parentStyleContext);
     // ASSERTION to check for bug 54454 sneaking back in...
     NS_ASSERTION(iContent, "null content in CreateAnonymousColFrames");
 
     // create the new col frame
     nsIFrame* colFrame = NS_NewTableColFrame(shell, styleContext);
     ((nsTableColFrame *) colFrame)->SetColType(aColType);
     colFrame->Init(iContent, aColGroupFrame, nsnull);
 
--- a/layout/xul/base/src/tree/src/nsTreeStyleCache.cpp
+++ b/layout/xul/base/src/tree/src/nsTreeStyleCache.cpp
@@ -96,18 +96,18 @@ nsTreeStyleCache::GetStyleContext(nsICSS
   // We're in a final state.
   // Look up our style context for this state.
   nsStyleContext* result = nsnull;
   if (mCache)
     result = static_cast<nsStyleContext*>(mCache->Get(currState));
   if (!result) {
     // We missed the cache. Resolve this pseudo-style.
     result = aPresContext->StyleSet()->
-      ResolvePseudoStyleFor(aContent, aPseudoElement,
-                            aContext, aComparator).get();
+      ResolveXULTreePseudoStyle(aContent, aPseudoElement,
+                                aContext, aComparator).get();
 
     // Put the style context in our table, transferring the owning reference to the table.
     if (!mCache) {
       mCache = new nsObjectHashtable(nsnull, nsnull, ReleaseStyleContext, nsnull);
       if (!mCache)
         return nsnull;
     }
     mCache->Put(currState, result);