Bug 604386 - Prune placeholder from text children, r=davidb, sr=bz, a=blocking
authorAlexander Surkov <surkov.alexander@gmail.com>
Sat, 16 Oct 2010 00:34:35 +0900
changeset 55877 16ef018faad175c87a1557fbc4779f87d66a1dba
parent 55876 c051f575d22f15e9464a016e7fc9ca29f4f7d726
child 55878 6bef1538745f2067cf1c440db41200e5478580c0
push idunknown
push userunknown
push dateunknown
reviewersdavidb, bz, blocking
bugs604386
milestone2.0b8pre
Bug 604386 - Prune placeholder from text children, r=davidb, sr=bz, a=blocking
accessible/src/base/nsAccTreeWalker.cpp
accessible/src/base/nsAccTreeWalker.h
accessible/tests/mochitest/attributes/test_text.html
accessible/tests/mochitest/events/test_focus.xul
accessible/tests/mochitest/tree/test_combobox.xul
content/base/public/nsIContent.h
content/base/src/nsGenericDOMDataNode.cpp
content/base/src/nsGenericDOMDataNode.h
content/base/src/nsGenericElement.cpp
content/base/src/nsGenericElement.h
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsComboboxControlFrame.h
layout/forms/nsFileControlFrame.cpp
layout/forms/nsFileControlFrame.h
layout/forms/nsGfxButtonControlFrame.cpp
layout/forms/nsGfxButtonControlFrame.h
layout/forms/nsIsIndexFrame.cpp
layout/forms/nsIsIndexFrame.h
layout/forms/nsTextControlFrame.cpp
layout/forms/nsTextControlFrame.h
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsIAnonymousContentCreator.h
layout/generic/nsVideoFrame.cpp
layout/generic/nsVideoFrame.h
layout/svg/base/src/nsSVGUseFrame.cpp
layout/xul/base/src/nsDocElementBoxFrame.cpp
--- a/accessible/src/base/nsAccTreeWalker.cpp
+++ b/accessible/src/base/nsAccTreeWalker.cpp
@@ -69,19 +69,21 @@ nsAccTreeWalker::
                   PRBool aWalkAnonContent) :
   mWeakShell(aShell), mState(nsnull)
 {
   NS_ASSERTION(aContent, "No node for the accessible tree walker!");
 
   if (aContent)
     mState = new WalkState(aContent);
 
-  mChildType = aWalkAnonContent ? nsIContent::eAllChildren :
+  mChildFilter = aWalkAnonContent ? nsIContent::eAllChildren :
                                   nsIContent::eAllButXBL;
 
+  mChildFilter |= nsIContent::eSkipPlaceholderContent;
+
   MOZ_COUNT_CTOR(nsAccTreeWalker);
 }
 
 nsAccTreeWalker::~nsAccTreeWalker()
 {
   // Clear state stack from memory
   while (mState)
     PopState();
@@ -94,17 +96,17 @@ nsAccTreeWalker::~nsAccTreeWalker()
 
 already_AddRefed<nsAccessible>
 nsAccTreeWalker::GetNextChildInternal(PRBool aNoWalkUp)
 {
   if (!mState || !mState->content)
     return nsnull;
 
   if (!mState->childList)
-    mState->childList = mState->content->GetChildren(mChildType);
+    mState->childList = mState->content->GetChildren(mChildFilter);
 
   nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
 
   PRUint32 length = 0;
   if (mState->childList)
     mState->childList->GetLength(&length);
 
   while (mState->childIdx < length) {
--- a/accessible/src/base/nsAccTreeWalker.h
+++ b/accessible/src/base/nsAccTreeWalker.h
@@ -86,13 +86,13 @@ private:
   PRBool PushState(nsIContent *aNode);
 
   /**
    * Pop state from stack.
    */
   void PopState();
 
   nsCOMPtr<nsIWeakReference> mWeakShell;
-  PRInt32 mChildType;
+  PRInt32 mChildFilter;
   WalkState* mState;
 };
 
 #endif 
--- a/accessible/tests/mochitest/attributes/test_text.html
+++ b/accessible/tests/mochitest/attributes/test_text.html
@@ -424,21 +424,18 @@
       ID = "area13";
       defAttrs = buildDefaultTextAttrs(ID, "12pt");
       attrs = { };
       testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
 
       ID = "area14";
       defAttrs = buildDefaultTextAttrs(ID, kInputFontSize);
 
-      // XXX: While we expose text leaf accessibles for placeholder we grab its
-      // style, bug 545817.
-      // attrs = { color: "rgb(109, 109, 109)" };
-      //testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
-      todo(false, "enable commented tests when bug 545817 is fixed");
+      attrs = { };
+      testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
 
       //////////////////////////////////////////////////////////////////////////
       // area15, embed char tests, "*plain*plain**bold*bold*"
       ID = "area15";
       defAttrs = buildDefaultTextAttrs(ID, "12pt");
 
       // p
       testTextAttrs(ID, 0, { }, { }, 0, 1);
--- a/accessible/tests/mochitest/events/test_focus.xul
+++ b/accessible/tests/mochitest/events/test_focus.xul
@@ -36,17 +36,17 @@
         return prettyName(aNodeOrID) + " click menu item";
       }
     }
     
     /**
      * Do tests.
      */
 
-    // gA11yEventDumpID = "eventdump"; // debug stuff
+    //gA11yEventDumpID = "eventdump"; // debug stuff
 
     var gQueue = null;
 
     function doTests()
     {
       // Test focus events.
       gQueue = new eventQueue(nsIAccessibleEvent.EVENT_FOCUS);
 
--- a/accessible/tests/mochitest/tree/test_combobox.xul
+++ b/accessible/tests/mochitest/tree/test_combobox.xul
@@ -49,19 +49,16 @@
 
       accTree = {
         role: ROLE_COMBOBOX,
         children: [
           {
             role: ROLE_ENTRY,
             children: [
               {
-                role: ROLE_TEXT_LEAF // HTML 5 placeholder attribute value
-              },
-              {
                 role: ROLE_TEXT_LEAF // Text node for the node's value
               }
             ]
           },
           {
             role: ROLE_COMBOBOX_LIST, // context menu
             children: []
           },
@@ -122,19 +119,16 @@
                 role: ROLE_COMBOBOX_OPTION
               }
             ]
           },
           {
             role: ROLE_ENTRY,
             children: [
               {
-                role: ROLE_TEXT_LEAF // HTML 5 placeholder attribute value
-              },
-              {
                 role: ROLE_TEXT_LEAF // Text node for the node's value
               }
             ]
           },
           {
             role: ROLE_COMBOBOX_LIST, // context menu popup
             children: [ ]
           }
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -170,30 +170,36 @@ public:
      * anonymous content and native anonymous children.
      *
      * @note the result children order is
      *   1. :before generated node
      *   2. XBL explicit children of the node
      *   3. native anonymous nodes
      *   4. :after generated node
      */
-    eAllButXBL = 1
+    eAllButXBL = 1,
+
+    /**
+     * Skip native anonymous content created for placeholder of HTML input,
+     * used in conjunction with eAllChildren or eAllButXBL.
+     */
+    eSkipPlaceholderContent = 2
   };
 
   /**
    * Return either the XBL explicit children of the node or the XBL flattened
-   * tree children of the node, depending on the child type, as well as any
+   * tree children of the node, depending on the filter, as well as
    * native anonymous children.
    *
    * @note calling this method with eAllButXBL will return children that are
    *  also in the eAllButXBL and eAllChildren child lists of other descendants
    *  of this node in the tree, but those other nodes cannot be reached from the
    *  eAllButXBL child list.
    */
-  virtual already_AddRefed<nsINodeList> GetChildren(PRInt32 aChildType) = 0;
+  virtual already_AddRefed<nsINodeList> GetChildren(PRUint32 aFilter) = 0;
 
   /**
    * Get whether this content is C++-generated anonymous content
    * @see nsIAnonymousContentCreator
    * @return whether this content is anonymous
    */
   PRBool IsRootOfNativeAnonymousSubtree() const
   {
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -574,17 +574,17 @@ nsGenericDOMDataNode::UnbindFromTree(PRB
   if (slots) {
     slots->mBindingParent = nsnull;
   }
 
   nsNodeUtils::ParentChainChanged(this);
 }
 
 already_AddRefed<nsINodeList>
-nsGenericDOMDataNode::GetChildren(PRInt32 aChildType)
+nsGenericDOMDataNode::GetChildren(PRUint32 aFilter)
 {
   return nsnull;
 }
 
 nsIAtom *
 nsGenericDOMDataNode::GetIDAttributeName() const
 {
   return nsnull;
--- a/content/base/src/nsGenericDOMDataNode.h
+++ b/content/base/src/nsGenericDOMDataNode.h
@@ -189,17 +189,17 @@ public:
 
   // Implementation for nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               PRBool aCompileEventHandlers);
   virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
                               PRBool aNullParent = PR_TRUE);
 
-  virtual already_AddRefed<nsINodeList> GetChildren(PRInt32 aChildType);
+  virtual already_AddRefed<nsINodeList> GetChildren(PRUint32 aFilter);
 
   virtual nsIAtom *GetIDAttributeName() const;
   virtual already_AddRefed<nsINodeInfo> GetExistingAttrNameFromQName(const nsAString& aStr) const;
   nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, PRBool aNotify)
   {
     return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
   }
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -3046,17 +3046,17 @@ nsGenericElement::UnbindFromTree(PRBool 
       mAttrsAndChildren.ChildAt(i)->UnbindFromTree(PR_TRUE, PR_FALSE);
     }
   }
 
   nsNodeUtils::ParentChainChanged(this);
 }
 
 already_AddRefed<nsINodeList>
-nsGenericElement::GetChildren(PRInt32 aChildType)
+nsGenericElement::GetChildren(PRUint32 aFilter)
 {
   nsRefPtr<nsBaseContentList> list = new nsBaseContentList();
   if (!list) {
     return nsnull;
   }
 
   nsIFrame *frame = GetPrimaryFrame();
 
@@ -3071,17 +3071,17 @@ nsGenericElement::GetChildren(PRInt32 aC
   // If XBL is bound to this node then append XBL anonymous content including
   // explict content altered by insertion point if we were requested for XBL
   // anonymous content, otherwise append explicit content with respect to
   // insertion point if any.
   nsINodeList *childList = nsnull;
 
   nsIDocument* document = GetOwnerDoc();
   if (document) {
-    if (aChildType != eAllButXBL) {
+    if (!(aFilter & eAllButXBL)) {
       childList = document->BindingManager()->GetXBLChildNodesFor(this);
       if (!childList) {
         childList = GetChildNodesList();
       }
 
     } else {
       childList = document->BindingManager()->GetContentListFor(this);
     }
@@ -3097,17 +3097,17 @@ nsGenericElement::GetChildren(PRInt32 aC
       list->AppendElement(child);
     }
   }
 
   if (frame) {
     // Append native anonymous content to the end.
     nsIAnonymousContentCreator* creator = do_QueryFrame(frame);
     if (creator) {
-      creator->AppendAnonymousContentTo(*list);
+      creator->AppendAnonymousContentTo(*list, aFilter);
     }
 
     // Append :after generated content.
     nsIFrame *afterFrame = nsLayoutUtils::GetAfterFrame(frame);
     if (afterFrame) {
       list->AppendElement(afterFrame->GetContent());
     }
   }
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -373,17 +373,17 @@ public:
   }
 
   // nsIContent interface methods
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               PRBool aCompileEventHandlers);
   virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
                               PRBool aNullParent = PR_TRUE);
-  virtual already_AddRefed<nsINodeList> GetChildren(PRInt32 aChildType);
+  virtual already_AddRefed<nsINodeList> GetChildren(PRUint32 aFilter);
   virtual nsIAtom *GetClassAttributeName() const;
   virtual already_AddRefed<nsINodeInfo> GetExistingAttrNameFromQName(const nsAString& aStr) const;
   nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, PRBool aNotify)
   {
     return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
   }
   virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1032,17 +1032,18 @@ nsComboboxControlFrame::CreateAnonymousC
 
   if (!aElements.AppendElement(mButtonContent))
     return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
 
 void
-nsComboboxControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements)
+nsComboboxControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                                 PRUint32 aFilter)
 {
   aElements.MaybeAppendElement(mDisplayContent);
   aElements.MaybeAppendElement(mButtonContent);
 }
 
 // XXXbz this is a for-now hack.  Now that display:inline-block works,
 // need to revisit this.
 class nsComboboxDisplayFrame : public nsBlockFrame {
--- a/layout/forms/nsComboboxControlFrame.h
+++ b/layout/forms/nsComboboxControlFrame.h
@@ -94,17 +94,18 @@ public:
   nsComboboxControlFrame(nsStyleContext* aContext);
   ~nsComboboxControlFrame();
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements);
+  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                        PRUint32 aFilter);
   virtual nsIFrame* CreateFrameFor(nsIContent* aContent);
 
 #ifdef ACCESSIBILITY
   virtual already_AddRefed<nsAccessible> CreateAccessible();
 #endif
 
   virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
 
--- a/layout/forms/nsFileControlFrame.cpp
+++ b/layout/forms/nsFileControlFrame.cpp
@@ -340,17 +340,18 @@ nsFileControlFrame::CreateAnonymousConte
 
   SyncAttr(kNameSpaceID_None, nsGkAtoms::size,     SYNC_TEXT);
   SyncAttr(kNameSpaceID_None, nsGkAtoms::disabled, SYNC_BOTH);
 
   return NS_OK;
 }
 
 void
-nsFileControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements)
+nsFileControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                             PRUint32 aFilter)
 {
   aElements.MaybeAppendElement(mTextContent);
   aElements.MaybeAppendElement(mBrowse);
   aElements.MaybeAppendElement(mCapture);
 }
 
 NS_QUERYFRAME_HEAD(nsFileControlFrame)
   NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
--- a/layout/forms/nsFileControlFrame.h
+++ b/layout/forms/nsFileControlFrame.h
@@ -88,17 +88,18 @@ public:
                               nsIAtom*        aAttribute,
                               PRInt32         aModType);
   virtual PRBool IsLeaf() const;
 
 
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements);
+  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                        PRUint32 aFilter);
 
 #ifdef ACCESSIBILITY
   virtual already_AddRefed<nsAccessible> CreateAccessible();
 #endif
 
   typedef PRBool (*AcceptAttrCallback)(const nsAString&, void*);
   void ParseAcceptAttribute(AcceptAttrCallback aCallback, void* aClosure) const;
 
--- a/layout/forms/nsGfxButtonControlFrame.cpp
+++ b/layout/forms/nsGfxButtonControlFrame.cpp
@@ -127,17 +127,18 @@ nsGfxButtonControlFrame::CreateAnonymous
   // set the value of the text node and add it to the child list
   mTextContent->SetText(label, PR_FALSE);
   if (!aElements.AppendElement(mTextContent))
     return NS_ERROR_OUT_OF_MEMORY;
   return NS_OK;
 }
 
 void
-nsGfxButtonControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements)
+nsGfxButtonControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                                  PRUint32 aFilter)
 {
   aElements.MaybeAppendElement(mTextContent);
 }
 
 // Create the text content used as label for the button.
 // The frame will be generated by the frame constructor.
 nsIFrame*
 nsGfxButtonControlFrame::CreateFrameFor(nsIContent*      aContent)
--- a/layout/forms/nsGfxButtonControlFrame.h
+++ b/layout/forms/nsGfxButtonControlFrame.h
@@ -71,17 +71,18 @@ public:
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const;
 #endif
 
   NS_DECL_QUERYFRAME
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements);
+  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                        PRUint32 aFilter);
   virtual nsIFrame* CreateFrameFor(nsIContent* aContent);
 
   // nsIFormControlFrame
   virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const; 
 
 
   NS_IMETHOD AttributeChanged(PRInt32         aNameSpaceID,
                               nsIAtom*        aAttribute,
--- a/layout/forms/nsIsIndexFrame.cpp
+++ b/layout/forms/nsIsIndexFrame.cpp
@@ -234,17 +234,18 @@ nsIsIndexFrame::CreateAnonymousContent(n
   NS_NewHTMLElement(getter_AddRefs(mPostHr), hrInfo.forget(), PR_FALSE);
   if (!mPostHr || !aElements.AppendElement(mPostHr))
     return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
 
 void
-nsIsIndexFrame::AppendAnonymousContentTo(nsBaseContentList& aElements)
+nsIsIndexFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                         PRUint32 aFilter)
 {
   aElements.MaybeAppendElement(mTextContent);
   aElements.MaybeAppendElement(mInputContent);
 }
 
 NS_QUERYFRAME_HEAD(nsIsIndexFrame)
   NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
   NS_QUERYFRAME_ENTRY(nsIStatefulFrame)
--- a/layout/forms/nsIsIndexFrame.h
+++ b/layout/forms/nsIsIndexFrame.h
@@ -93,17 +93,18 @@ public:
   NS_IMETHOD AttributeChanged(PRInt32         aNameSpaceID,
                               nsIAtom*        aAttribute,
                               PRInt32         aModType);
 
   void           SetFocus(PRBool aOn, PRBool aRepaint);
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements);
+  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                        PRUint32 aFilter);
 
   NS_IMETHOD OnSubmit(nsPresContext* aPresContext);
 
   //nsIStatefulFrame
   NS_IMETHOD SaveState(SpecialStateID aStateID, nsPresState** aState);
   NS_IMETHOD RestoreState(nsPresState* aState);
 
 protected:
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -464,23 +464,25 @@ nsTextControlFrame::CreateAnonymousConte
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   return NS_OK;
 }
 
 void
-nsTextControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements)
+nsTextControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                             PRUint32 aFilter)
 {
   nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
   NS_ASSERTION(txtCtrl, "Content not a text control element");
 
   aElements.MaybeAppendElement(txtCtrl->GetRootEditorNode());
-  aElements.MaybeAppendElement(txtCtrl->GetPlaceholderNode());
+  if (!(aFilter & nsIContent::eSkipPlaceholderContent))
+    aElements.MaybeAppendElement(txtCtrl->GetPlaceholderNode());
 }
 
 nscoord
 nsTextControlFrame::GetMinWidth(nsIRenderingContext* aRenderingContext)
 {
   // Our min width is just our preferred width if we have auto width.
   nscoord result;
   DISPLAY_MIN_WIDTH(this, result);
--- a/layout/forms/nsTextControlFrame.h
+++ b/layout/forms/nsTextControlFrame.h
@@ -113,17 +113,18 @@ public:
     // nsStackFrame is already both of these, but that's somewhat bogus,
     // and we really mean it.
     return nsStackFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements);
+  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                        PRUint32 aFilter);
 
   // Utility methods to set current widget state
 
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
                                  nsFrameList&    aChildList);
 
 //==== BEGIN NSIFORMCONTROLFRAME
   virtual void SetFocus(PRBool aOn , PRBool aRepaint); 
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -104,19 +104,20 @@ nsHTMLScrollFrame::nsHTMLScrollFrame(nsI
 
 nsresult
 nsHTMLScrollFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
 {
   return mInner.CreateAnonymousContent(aElements);
 }
 
 void
-nsHTMLScrollFrame::AppendAnonymousContentTo(nsBaseContentList& aElements)
+nsHTMLScrollFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                            PRUint32 aFilter)
 {
-  mInner.AppendAnonymousContentTo(aElements);
+  mInner.AppendAnonymousContentTo(aElements, aFilter);
 }
 
 void
 nsHTMLScrollFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   mInner.Destroy();
   nsHTMLContainerFrame::DestroyFrom(aDestructRoot);
 }
@@ -968,19 +969,20 @@ nsMargin nsGfxScrollFrameInner::GetDesir
 
 nsresult
 nsXULScrollFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
 {
   return mInner.CreateAnonymousContent(aElements);
 }
 
 void
-nsXULScrollFrame::AppendAnonymousContentTo(nsBaseContentList& aElements)
+nsXULScrollFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                           PRUint32 aFilter)
 {
-  mInner.AppendAnonymousContentTo(aElements);
+  mInner.AppendAnonymousContentTo(aElements, aFilter);
 }
 
 void
 nsXULScrollFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   mInner.Destroy();
   nsBoxFrame::DestroyFrom(aDestructRoot);
 }
@@ -2227,17 +2229,18 @@ nsGfxScrollFrameInner::CreateAnonymousCo
     if (!aElements.AppendElement(mScrollCornerContent))
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
 
 void
-nsGfxScrollFrameInner::AppendAnonymousContentTo(nsBaseContentList& aElements)
+nsGfxScrollFrameInner::AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                                PRUint32 aFilter)
 {
   aElements.MaybeAppendElement(mHScrollbarContent);
   aElements.MaybeAppendElement(mVScrollbarContent);
   aElements.MaybeAppendElement(mScrollCornerContent);
 }
 
 void
 nsGfxScrollFrameInner::Destroy()
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -77,17 +77,17 @@ public:
   ScrollbarStyles GetScrollbarStylesFromFrame() const;
 
   // If a child frame was added or removed on the scrollframe,
   // reload our child frame list.
   // We need this if a scrollbar frame is recreated.
   void ReloadChildFrames();
 
   nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
-  void AppendAnonymousContentTo(nsBaseContentList& aElements);
+  void AppendAnonymousContentTo(nsBaseContentList& aElements, PRUint32 aFilter);
   nsresult FireScrollPortEvent();
   void PostOverflowEvent();
   void Destroy();
 
   nsresult BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                             const nsRect&           aDirtyRect,
                             const nsDisplayListSet& aLists);
 
@@ -389,17 +389,18 @@ public:
   virtual nsPoint GetPositionOfChildIgnoringScrolling(nsIFrame* aChild)
   { nsPoint pt = aChild->GetPosition();
     if (aChild == mInner.GetScrolledFrame()) pt += GetScrollPosition();
     return pt;
   }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements);
+  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                        PRUint32 aFilter);
 
   // nsIScrollableFrame
   virtual nsIFrame* GetScrolledFrame() const {
     return mInner.GetScrolledFrame();
   }
   virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const {
     return mInner.GetScrollbarStylesFromFrame();
   }
@@ -587,17 +588,18 @@ public:
   virtual nsPoint GetPositionOfChildIgnoringScrolling(nsIFrame* aChild)
   { nsPoint pt = aChild->GetPosition();
     if (aChild == mInner.GetScrolledFrame()) pt += GetScrollPosition();
     return pt;
   }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements);
+  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                        PRUint32 aFilter);
 
   virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState);
   virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState);
   virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState);
   virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState);
 
   NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState);
   NS_IMETHOD GetPadding(nsMargin& aPadding);
--- a/layout/generic/nsIAnonymousContentCreator.h
+++ b/layout/generic/nsIAnonymousContentCreator.h
@@ -68,19 +68,22 @@ public:
    *       responsible for calling UnbindFromTree on the elements it returned
    *       from CreateAnonymousContent when appropriate (i.e. before releasing
    *       them).
    */
   virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements)=0;
 
   /**
    * Appends "native" anonymous children created by CreateAnonymousContent()
-   * to the given content list.
+   * to the given content list depending on the filter.
+   *
+   * @see nsIContent::GetChildren for set of values used for filter.
    */
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements) = 0;
+  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                        PRUint32 aFilter) = 0;
 
   /**
    * Implementations can override this method to create special frames for the
    * anonymous content returned from CreateAnonymousContent.
    * By default this method returns nsnull, which means the default frame
    * is created.
    */
   virtual nsIFrame* CreateFrameFor(nsIContent* aContent) { return nsnull; }
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -131,17 +131,18 @@ nsVideoFrame::CreateAnonymousContent(nsT
   NS_TrustedNewXULElement(getter_AddRefs(mVideoControls), nodeInfo.forget());
   if (!aElements.AppendElement(mVideoControls))
     return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
 
 void
-nsVideoFrame::AppendAnonymousContentTo(nsBaseContentList& aElements)
+nsVideoFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                       PRUint32 aFliter)
 {
   aElements.MaybeAppendElement(mPosterImage);
   aElements.MaybeAppendElement(mVideoControls);
 }
 
 void
 nsVideoFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
--- a/layout/generic/nsVideoFrame.h
+++ b/layout/generic/nsVideoFrame.h
@@ -99,17 +99,18 @@ public:
   virtual nsIAtom* GetType() const;
 
   virtual PRBool IsFrameOfType(PRUint32 aFlags) const
   {
     return nsSplittableFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced));
   }
   
   virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements);
+  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                        PRUint32 aFilters);
 
   nsIContent* GetPosterImage() { return mPosterImage; }
 
   // Returns PR_TRUE if we should display the poster. Note that once we show
   // a video frame, the poster will never be displayed again.
   PRBool ShouldDisplayPoster();
 
 #ifdef DEBUG
--- a/layout/svg/base/src/nsSVGUseFrame.cpp
+++ b/layout/svg/base/src/nsSVGUseFrame.cpp
@@ -84,17 +84,18 @@ public:
   NS_IMETHOD GetFrameName(nsAString& aResult) const
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGUse"), aResult);
   }
 #endif
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements);
+  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                        PRUint32 aFilter);
 };
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsIFrame*
 NS_NewSVGUseFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
@@ -178,14 +179,15 @@ nsSVGUseFrame::CreateAnonymousContent(ns
   if (!clone)
     return NS_ERROR_FAILURE;
   if (!aElements.AppendElement(clone))
     return NS_ERROR_OUT_OF_MEMORY;
   return NS_OK;
 }
 
 void
-nsSVGUseFrame::AppendAnonymousContentTo(nsBaseContentList& aElements)
+nsSVGUseFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                        PRUint32 aFilter)
 {
   nsSVGUseElement *use = static_cast<nsSVGUseElement*>(mContent);
   nsIContent* clone = use->GetAnonymousContent();
   aElements.MaybeAppendElement(clone);
 }
--- a/layout/xul/base/src/nsDocElementBoxFrame.cpp
+++ b/layout/xul/base/src/nsDocElementBoxFrame.cpp
@@ -70,17 +70,18 @@ public:
   nsDocElementBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext)
     :nsBoxFrame(aShell, aContext, PR_TRUE) {}
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements);
+  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                        PRUint32 aFilter);
 
   virtual PRBool IsFrameOfType(PRUint32 aFlags) const
   {
     // Override nsBoxFrame.
     if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced))
       return PR_FALSE;
     return nsBoxFrame::IsFrameOfType(aFlags);
   }
@@ -147,17 +148,18 @@ nsDocElementBoxFrame::CreateAnonymousCon
 
   if (!aElements.AppendElement(mTooltipContent))
     return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
 
 void
-nsDocElementBoxFrame::AppendAnonymousContentTo(nsBaseContentList& aElements)
+nsDocElementBoxFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                               PRUint32 aFilter)
 {
   aElements.MaybeAppendElement(mPopupgroupContent);
   aElements.MaybeAppendElement(mTooltipContent);
 }
 
 NS_QUERYFRAME_HEAD(nsDocElementBoxFrame)
   NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
 NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)