bug 1016545 - Provide an iterator that iterates over all children of an element r=bz
authorTrevor Saunders <trev.saunders@gmail.com>
Wed, 16 Jul 2014 14:41:57 -0400
changeset 220795 2522daeec7f738024cbef2b12e02d9596f4b10b4
parent 220794 d9382edf1265d22301667a03602811f8df18ffcd
child 220796 060e0b2acfbdd36842f7a64de34f0c24f6225f52
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1016545
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1016545 - Provide an iterator that iterates over all children of an element r=bz
accessible/base/TreeWalker.cpp
content/base/src/ChildIterator.cpp
content/base/src/ChildIterator.h
content/base/src/FragmentOrElement.cpp
content/base/src/moz.build
layout/forms/nsColorControlFrame.cpp
layout/forms/nsColorControlFrame.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/nsMeterFrame.cpp
layout/forms/nsMeterFrame.h
layout/forms/nsNumberControlFrame.cpp
layout/forms/nsNumberControlFrame.h
layout/forms/nsProgressFrame.cpp
layout/forms/nsProgressFrame.h
layout/forms/nsRangeFrame.cpp
layout/forms/nsRangeFrame.h
layout/forms/nsTextControlFrame.cpp
layout/forms/nsTextControlFrame.h
layout/generic/nsCanvasFrame.cpp
layout/generic/nsCanvasFrame.h
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsIAnonymousContentCreator.h
layout/generic/nsVideoFrame.cpp
layout/generic/nsVideoFrame.h
layout/svg/nsSVGUseFrame.cpp
layout/xul/nsDocElementBoxFrame.cpp
--- a/accessible/base/TreeWalker.cpp
+++ b/accessible/base/TreeWalker.cpp
@@ -4,59 +4,58 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "TreeWalker.h"
 
 #include "Accessible.h"
 #include "nsAccessibilityService.h"
 #include "DocAccessible.h"
 
+#include "mozilla/dom/ChildIterator.h"
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // WalkState
 ////////////////////////////////////////////////////////////////////////////////
 
 namespace mozilla {
 namespace a11y {
 
 struct WalkState
 {
-  WalkState(nsIContent *aContent) :
-    content(aContent), childIdx(0), prevState(nullptr) {}
+  WalkState(nsIContent *aContent, uint32_t aFilter) :
+    content(aContent), prevState(nullptr), iter(aContent, aFilter) {}
 
   nsCOMPtr<nsIContent> content;
-  nsCOMPtr<nsINodeList> childList;
-  uint32_t childIdx;
   WalkState *prevState;
+  dom::AllChildrenIterator iter;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 ////////////////////////////////////////////////////////////////////////////////
 // TreeWalker
 ////////////////////////////////////////////////////////////////////////////////
 
 TreeWalker::
   TreeWalker(Accessible* aContext, nsIContent* aContent, uint32_t aFlags) :
   mDoc(aContext->Document()), mContext(aContext),
   mFlags(aFlags), mState(nullptr)
 {
   NS_ASSERTION(aContent, "No node for the accessible tree walker!");
 
-  if (aContent)
-    mState = new WalkState(aContent);
-
   mChildFilter = mContext->CanHaveAnonChildren() ?
     nsIContent::eAllChildren : nsIContent::eAllButXBL;
+  mChildFilter |= nsIContent::eSkipPlaceholderContent;
 
-  mChildFilter |= nsIContent::eSkipPlaceholderContent;
+  if (aContent)
+    mState = new WalkState(aContent, mChildFilter);
 
   MOZ_COUNT_CTOR(TreeWalker);
 }
 
 TreeWalker::~TreeWalker()
 {
   // Clear state stack from memory
   while (mState)
@@ -69,38 +68,28 @@ TreeWalker::~TreeWalker()
 // TreeWalker: private
 
 Accessible*
 TreeWalker::NextChildInternal(bool aNoWalkUp)
 {
   if (!mState || !mState->content)
     return nullptr;
 
-  if (!mState->childList)
-    mState->childList = mState->content->GetChildren(mChildFilter);
-
-  uint32_t length = 0;
-  if (mState->childList)
-    mState->childList->GetLength(&length);
-
-  while (mState->childIdx < length) {
-    nsIContent* childNode = mState->childList->Item(mState->childIdx);
-    mState->childIdx++;
-
+  while (nsIContent* childNode = mState->iter.GetNextChild()) {
     bool isSubtreeHidden = false;
     Accessible* accessible = mFlags & eWalkCache ?
       mDoc->GetAccessible(childNode) :
       GetAccService()->GetOrCreateAccessible(childNode, mContext,
                                              &isSubtreeHidden);
 
     if (accessible)
       return accessible;
 
     // Walk down into subtree to find accessibles.
-    if (!isSubtreeHidden) {
+    if (!isSubtreeHidden && childNode->IsElement()) {
       PushState(childNode);
       accessible = NextChildInternal(true);
       if (accessible)
         return accessible;
     }
   }
 
   // No more children, get back to the parent.
@@ -118,24 +107,17 @@ TreeWalker::NextChildInternal(bool aNoWa
     return nullptr;
 
   while (anchorNode != mContext->GetNode()) {
     nsINode* parentNode = anchorNode->GetFlattenedTreeParent();
     if (!parentNode || !parentNode->IsElement())
       return nullptr;
 
     PushState(parentNode->AsElement());
-    mState->childList = mState->content->GetChildren(mChildFilter);
-    length = 0;
-    if (mState->childList)
-      mState->childList->GetLength(&length);
-
-    while (mState->childIdx < length) {
-      nsIContent* childNode = mState->childList->Item(mState->childIdx);
-      mState->childIdx++;
+    while (nsIContent* childNode = mState->iter.GetNextChild()) {
       if (childNode == anchorNode)
         return NextChildInternal(false);
     }
     PopState();
 
     anchorNode = parentNode->AsElement();
   }
 
@@ -148,12 +130,12 @@ TreeWalker::PopState()
   WalkState* prevToLastState = mState->prevState;
   delete mState;
   mState = prevToLastState;
 }
 
 void
 TreeWalker::PushState(nsIContent* aContent)
 {
-  WalkState* nextToLastState = new WalkState(aContent);
+  WalkState* nextToLastState = new WalkState(aContent, mChildFilter);
   nextToLastState->prevState = mState;
   mState = nextToLastState;
 }
--- a/content/base/src/ChildIterator.cpp
+++ b/content/base/src/ChildIterator.cpp
@@ -5,16 +5,18 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ChildIterator.h"
 #include "nsContentUtils.h"
 #include "mozilla/dom/XBLChildrenElement.h"
 #include "mozilla/dom/HTMLContentElement.h"
 #include "mozilla/dom/HTMLShadowElement.h"
 #include "mozilla/dom/ShadowRoot.h"
+#include "nsIAnonymousContentCreator.h"
+#include "nsIFrame.h"
 
 namespace mozilla {
 namespace dom {
 
 class MatchedNodes {
 public:
   MatchedNodes(HTMLContentElement* aInsertionPoint)
     : mIsContentElement(true), mContentElement(aInsertionPoint) {}
@@ -149,35 +151,39 @@ ExplicitChildIterator::GetNextChild()
       // return from this iterator.
       break;
     }
   }
 
   return mChild;
 }
 
-FlattenedChildIterator::FlattenedChildIterator(nsIContent* aParent)
-  : ExplicitChildIterator(aParent), mXBLInvolved(false)
+void
+FlattenedChildIterator::Init(bool aIgnoreXBL)
 {
+  if (aIgnoreXBL) {
+    return;
+  }
+
   nsXBLBinding* binding =
-    aParent->OwnerDoc()->BindingManager()->GetBindingWithContent(aParent);
+    mParent->OwnerDoc()->BindingManager()->GetBindingWithContent(mParent);
 
   if (binding) {
     nsIContent* anon = binding->GetAnonymousContent();
     if (anon) {
       mParent = anon;
       mXBLInvolved = true;
     }
   }
 
   // We set mXBLInvolved to true if either:
   // - The node we're iterating has a binding with content attached to it.
   // - The node is generated XBL content and has an <xbl:children> child.
-  if (!mXBLInvolved && aParent->GetBindingParent()) {
-    for (nsIContent* child = aParent->GetFirstChild();
+  if (!mXBLInvolved && mParent->GetBindingParent()) {
+    for (nsIContent* child = mParent->GetFirstChild();
          child;
          child = child->GetNextSibling()) {
       if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
         MOZ_ASSERT(child->GetBindingParent());
         mXBLInvolved = true;
         break;
       }
     }
@@ -276,10 +282,68 @@ ExplicitChildIterator::GetPreviousChild(
 
   if (!mChild) {
     mIsFirst = true;
   }
 
   return mChild;
 }
 
+nsIContent*
+AllChildrenIterator::GetNextChild()
+{
+  if (mPhase == eNeedBeforeKid) {
+    mPhase = eNeedExplicitKids;
+    nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
+    if (frame) {
+      nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
+      if (beforeFrame) {
+        return beforeFrame->GetContent();
+      }
+    }
+  }
+
+  if (mPhase == eNeedExplicitKids) {
+    nsIContent* kid = ExplicitChildIterator::GetNextChild();
+    if (kid) {
+      return kid;
+    }
+
+    mPhase = eNeedAnonKids;
+  }
+
+  if (mPhase == eNeedAnonKids) {
+    if (mAnonKids.IsEmpty()) {
+      nsIAnonymousContentCreator* ac =
+        do_QueryFrame(mOriginalContent->GetPrimaryFrame());
+      if (ac) {
+        ac->AppendAnonymousContentTo(mAnonKids, mFlags);
+      }
+    }
+
+    if (!mAnonKids.IsEmpty()) {
+      nsIContent* nextKid = mAnonKids[0];
+      mAnonKids.RemoveElementAt(0);
+      if (mAnonKids.IsEmpty()) {
+        mPhase = eNeedAfterKid;
+      }
+
+      return nextKid;
+    }
+
+    mPhase = eNeedAfterKid;
+  }
+
+  if (mPhase == eNeedAfterKid) {
+    mPhase = eDone;
+    nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
+    if (frame) {
+      nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
+      if (afterFrame) {
+        return afterFrame->GetContent();
+      }
+    }
+  }
+
+  return nullptr;
+}
 } // namespace dom
 } // namespace mozilla
--- a/content/base/src/ChildIterator.h
+++ b/content/base/src/ChildIterator.h
@@ -2,16 +2,18 @@
 /* vim: set ts=2 sw=2 et tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef ChildIterator_h
 #define ChildIterator_h
 
+#include "nsIContent.h"
+
 /**
  * Iterates over the children on a node. If a child is an insertion point,
  * iterates over the children inserted there instead, or the default content
  * if no children are inserted there.
  *
  * The FlattenedChildIterator expands any anonymous content bound from an XBL
  * binding's <xbl:content> element.
  */
@@ -102,22 +104,79 @@ protected:
 };
 
 // Iterates over the flattened children of a node, which accounts for anonymous
 // children and nodes moved by insertion points. If a node has anonymous
 // children, those are iterated over.
 class FlattenedChildIterator : public ExplicitChildIterator
 {
 public:
-  FlattenedChildIterator(nsIContent* aParent);
+  FlattenedChildIterator(nsIContent* aParent)
+    : ExplicitChildIterator(aParent), mXBLInvolved(false)
+  {
+    Init(false);
+  }
 
   bool XBLInvolved() { return mXBLInvolved; }
 
-private:
+protected:
+  /**
+   * This constructor is a hack to help AllChildrenIterator which sometimes
+   * doesn't want to consider XBL.
+   */
+  FlattenedChildIterator(nsIContent* aParent, bool aIgnoreXBL)
+  : ExplicitChildIterator(aParent), mXBLInvolved(false)
+  {
+    Init(aIgnoreXBL);
+  }
+
+  void Init(bool aIgnoreXBL);
+
   // For certain optimizations, nsCSSFrameConstructor needs to know if the
   // child list of the element that we're iterating matches its .childNodes.
   bool mXBLInvolved;
 };
 
+/**
+ * AllChildrenIterator returns the children of a element including before /
+ * after content and optionally XBL children.  It assumes that no mutation of
+ * the DOM or frame tree takes place during iteration, and will break horribly
+ * if that is not true.
+ */
+class AllChildrenIterator : private FlattenedChildIterator
+{
+public:
+  AllChildrenIterator(nsIContent* aNode, uint32_t aFlags) :
+    FlattenedChildIterator(aNode, (aFlags & nsIContent::eAllButXBL)),
+    mOriginalContent(aNode), mFlags(aFlags),
+    mPhase(eNeedBeforeKid) {}
+
+#ifdef DEBUG
+  ~AllChildrenIterator() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); }
+#endif
+
+  nsIContent* GetNextChild();
+
+private:
+  enum IteratorPhase
+  {
+    eNeedBeforeKid,
+    eNeedExplicitKids,
+    eNeedAnonKids,
+    eNeedAfterKid,
+    eDone
+  };
+
+  nsIContent* mOriginalContent;
+  nsTArray<nsIContent*> mAnonKids;
+  uint32_t mFlags;
+  IteratorPhase mPhase;
+#ifdef DEBUG
+  // XXX we should really assert there are no frame tree changes as well, but
+  // there's no easy way to do that.
+  nsMutationGuard mMutationGuard;
+#endif
+};
+
 } // namespace dom
 } // namespace mozilla
 
 #endif
--- a/content/base/src/FragmentOrElement.cpp
+++ b/content/base/src/FragmentOrElement.cpp
@@ -656,58 +656,19 @@ FragmentOrElement::~FragmentOrElement()
     NS_RELEASE(mParent);
   }
 }
 
 already_AddRefed<nsINodeList>
 FragmentOrElement::GetChildren(uint32_t aFilter)
 {
   nsRefPtr<nsSimpleContentList> list = new nsSimpleContentList(this);
-  if (!list) {
-    return nullptr;
-  }
-
-  nsIFrame *frame = GetPrimaryFrame();
-
-  // Append :before generated content.
-  if (frame) {
-    nsIFrame *beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
-    if (beforeFrame) {
-      list->AppendElement(beforeFrame->GetContent());
-    }
-  }
-
-  // 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.
-  if (!(aFilter & eAllButXBL)) {
-    FlattenedChildIterator iter(this);
-    for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
-      list->AppendElement(child);
-    }
-  } else {
-    ExplicitChildIterator iter(this);
-    for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
-      list->AppendElement(child);
-    }
-  }
-
-  if (frame) {
-    // Append native anonymous content to the end.
-    nsIAnonymousContentCreator* creator = do_QueryFrame(frame);
-    if (creator) {
-      creator->AppendAnonymousContentTo(*list, aFilter);
-    }
-
-    // Append :after generated content.
-    nsIFrame *afterFrame = nsLayoutUtils::GetAfterFrame(frame);
-    if (afterFrame) {
-      list->AppendElement(afterFrame->GetContent());
-    }
+  AllChildrenIterator iter(this, aFilter);
+  while (nsIContent* kid = iter.GetNextChild()) {
+    list->AppendElement(kid);
   }
 
   return list.forget();
 }
 
 static nsIContent*
 FindChromeAccessOnlySubtreeOwner(nsIContent* aContent)
 {
--- a/content/base/src/moz.build
+++ b/content/base/src/moz.build
@@ -56,16 +56,17 @@ if CONFIG['INTEL_ARCHITECTURE']:
     SOURCES['nsTextFragmentSSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
 
 EXPORTS.mozilla += [
     'FeedWriterEnabled.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'Attr.h',
+    'ChildIterator.h',
     'Comment.h',
     'DocumentFragment.h',
     'DocumentType.h',
     'DOMImplementation.h',
     'DOMMatrix.h',
     'DOMParser.h',
     'DOMPoint.h',
     'DOMQuad.h',
--- a/layout/forms/nsColorControlFrame.cpp
+++ b/layout/forms/nsColorControlFrame.cpp
@@ -78,20 +78,22 @@ nsColorControlFrame::CreateAnonymousCont
   if (!aElements.AppendElement(ContentInfo(mColorContent, newStyleContext))) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
 
 void
-nsColorControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+nsColorControlFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                               uint32_t aFilter)
 {
-  aElements.MaybeAppendElement(mColorContent);
+  if (mColorContent) {
+    aElements.AppendElement(mColorContent);
+  }
 }
 
 nsresult
 nsColorControlFrame::UpdateColor()
 {
   // Get the color from the "value" property of our content; it will return the
   // default color (through the sanitization algorithm) if there is none.
   nsAutoString color;
--- a/layout/forms/nsColorControlFrame.h
+++ b/layout/forms/nsColorControlFrame.h
@@ -32,17 +32,17 @@ public:
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
   // nsIFrame
   virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
                                     nsIAtom* aAttribute,
                                     int32_t  aModType) MOZ_OVERRIDE;
   virtual bool IsLeaf() const MOZ_OVERRIDE { return true; }
   virtual nsContainerFrame* GetContentInsertionFrame() MOZ_OVERRIDE;
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1179,21 +1179,26 @@ nsComboboxControlFrame::CreateAnonymousC
 
   if (!aElements.AppendElement(mButtonContent))
     return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
 
 void
-nsComboboxControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+nsComboboxControlFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                                  uint32_t aFilter)
 {
-  aElements.MaybeAppendElement(mDisplayContent);
-  aElements.MaybeAppendElement(mButtonContent);
+  if (mDisplayContent) {
+    aElements.AppendElement(mDisplayContent);
+  }
+
+  if (mButtonContent) {
+    aElements.AppendElement(mButtonContent);
+  }
 }
 
 // XXXbz this is a for-now hack.  Now that display:inline-block works,
 // need to revisit this.
 class nsComboboxDisplayFrame : public nsBlockFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
--- a/layout/forms/nsComboboxControlFrame.h
+++ b/layout/forms/nsComboboxControlFrame.h
@@ -54,17 +54,17 @@ public:
   nsComboboxControlFrame(nsStyleContext* aContext);
   ~nsComboboxControlFrame();
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
   virtual nsIFrame* CreateFrameFor(nsIContent* aContent) MOZ_OVERRIDE;
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
   virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
--- a/layout/forms/nsFileControlFrame.cpp
+++ b/layout/forms/nsFileControlFrame.cpp
@@ -145,21 +145,26 @@ nsFileControlFrame::CreateAnonymousConte
                                    mMouseListener, false);
 
   SyncDisabledState();
 
   return NS_OK;
 }
 
 void
-nsFileControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+nsFileControlFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                              uint32_t aFilter)
 {
-  aElements.MaybeAppendElement(mBrowse);
-  aElements.MaybeAppendElement(mTextContent);
+  if (mBrowse) {
+    aElements.AppendElement(mBrowse);
+  }
+
+  if (mTextContent) {
+    aElements.AppendElement(mTextContent);
+  }
 }
 
 NS_QUERYFRAME_HEAD(nsFileControlFrame)
   NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
   NS_QUERYFRAME_ENTRY(nsIFormControlFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsBlockFrame)
 
 void 
--- a/layout/forms/nsFileControlFrame.h
+++ b/layout/forms/nsFileControlFrame.h
@@ -52,17 +52,17 @@ public:
   virtual void ContentStatesChanged(mozilla::EventStates aStates) MOZ_OVERRIDE;
   virtual bool IsLeaf() const MOZ_OVERRIDE
   {
     return true;
   }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
   typedef bool (*AcceptAttrCallback)(const nsAString&, void*);
 
--- a/layout/forms/nsGfxButtonControlFrame.cpp
+++ b/layout/forms/nsGfxButtonControlFrame.cpp
@@ -64,20 +64,22 @@ nsGfxButtonControlFrame::CreateAnonymous
   // set the value of the text node and add it to the child list
   mTextContent->SetText(label, false);
   aElements.AppendElement(mTextContent);
 
   return NS_OK;
 }
 
 void
-nsGfxButtonControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+nsGfxButtonControlFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                                   uint32_t aFilter)
 {
-  aElements.MaybeAppendElement(mTextContent);
+  if (mTextContent) {
+    aElements.AppendElement(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)
 {
   nsIFrame * newFrame = nullptr;
--- a/layout/forms/nsGfxButtonControlFrame.h
+++ b/layout/forms/nsGfxButtonControlFrame.h
@@ -35,17 +35,17 @@ public:
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
   NS_DECL_QUERYFRAME
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
   virtual nsIFrame* CreateFrameFor(nsIContent* aContent) MOZ_OVERRIDE;
 
   virtual nsresult AttributeChanged(int32_t         aNameSpaceID,
                                     nsIAtom*        aAttribute,
                                     int32_t         aModType) MOZ_OVERRIDE;
 
   virtual bool IsLeaf() const MOZ_OVERRIDE;
--- a/layout/forms/nsMeterFrame.cpp
+++ b/layout/forms/nsMeterFrame.cpp
@@ -74,20 +74,22 @@ nsMeterFrame::CreateAnonymousContent(nsT
   if (!aElements.AppendElement(ContentInfo(mBarDiv, newStyleContext))) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
 
 void
-nsMeterFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+nsMeterFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                        uint32_t aFilter)
 {
-  aElements.MaybeAppendElement(mBarDiv);
+  if (mBarDiv) {
+    aElements.AppendElement(mBarDiv);
+  }
 }
 
 NS_QUERYFRAME_HEAD(nsMeterFrame)
   NS_QUERYFRAME_ENTRY(nsMeterFrame)
   NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
 
--- a/layout/forms/nsMeterFrame.h
+++ b/layout/forms/nsMeterFrame.h
@@ -37,17 +37,17 @@ public:
     return MakeFrameName(NS_LITERAL_STRING("Meter"), aResult);
   }
 #endif
 
   virtual bool IsLeaf() const MOZ_OVERRIDE { return true; }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
   virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
                                     nsIAtom* aAttribute,
                                     int32_t  aModType) MOZ_OVERRIDE;
 
   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                  nsSize aCBSize, nscoord aAvailableWidth,
--- a/layout/forms/nsNumberControlFrame.cpp
+++ b/layout/forms/nsNumberControlFrame.cpp
@@ -671,21 +671,23 @@ nsNumberControlFrame::ShouldUseNativeSty
                                             STYLES_DISABLING_NATIVE_THEMING) &&
     spinDownFrame &&
     spinDownFrame->StyleDisplay()->mAppearance == NS_THEME_SPINNER_DOWN_BUTTON &&
     !PresContext()->HasAuthorSpecifiedRules(spinDownFrame,
                                             STYLES_DISABLING_NATIVE_THEMING);
 }
 
 void
-nsNumberControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+nsNumberControlFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                                uint32_t aFilter)
 {
   // Only one direct anonymous child:
-  aElements.MaybeAppendElement(mOuterWrapper);
+  if (mOuterWrapper) {
+    aElements.AppendElement(mOuterWrapper);
+  }
 }
 
 void
 nsNumberControlFrame::SetValueOfAnonTextControl(const nsAString& aValue)
 {
   if (mHandlingInputEvent) {
     // We have been called while our HTMLInputElement is processing a DOM
     // 'input' event targeted at our anonymous text control. Our
--- a/layout/forms/nsNumberControlFrame.h
+++ b/layout/forms/nsNumberControlFrame.h
@@ -63,17 +63,17 @@ public:
                       nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
                                     nsIAtom* aAttribute,
                                     int32_t  aModType) MOZ_OVERRIDE;
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE {
     return MakeFrameName(NS_LITERAL_STRING("NumberControl"), aResult);
   }
 #endif
 
--- a/layout/forms/nsProgressFrame.cpp
+++ b/layout/forms/nsProgressFrame.cpp
@@ -71,20 +71,22 @@ nsProgressFrame::CreateAnonymousContent(
   if (!aElements.AppendElement(ContentInfo(mBarDiv, newStyleContext))) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
 
 void
-nsProgressFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+nsProgressFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                           uint32_t aFilter)
 {
-  aElements.MaybeAppendElement(mBarDiv);
+  if (mBarDiv) {
+    aElements.AppendElement(mBarDiv);
+  }
 }
 
 NS_QUERYFRAME_HEAD(nsProgressFrame)
   NS_QUERYFRAME_ENTRY(nsProgressFrame)
   NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
 
--- a/layout/forms/nsProgressFrame.h
+++ b/layout/forms/nsProgressFrame.h
@@ -42,17 +42,17 @@ public:
     return MakeFrameName(NS_LITERAL_STRING("Progress"), aResult);
   }
 #endif
 
   virtual bool IsLeaf() const MOZ_OVERRIDE { return true; }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
   virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
                                     nsIAtom* aAttribute,
                                     int32_t  aModType) MOZ_OVERRIDE;
 
   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                  nsSize aCBSize, nscoord aAvailableWidth,
--- a/layout/forms/nsRangeFrame.cpp
+++ b/layout/forms/nsRangeFrame.cpp
@@ -149,22 +149,30 @@ nsRangeFrame::CreateAnonymousContent(nsT
   // Create the ::-moz-range-thumb pseudo-element (a div):
   rv = MakeAnonymousDiv(getter_AddRefs(mThumbDiv),
                         nsCSSPseudoElements::ePseudo_mozRangeThumb,
                         aElements);
   return rv;
 }
 
 void
-nsRangeFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+nsRangeFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                        uint32_t aFilter)
 {
-  aElements.MaybeAppendElement(mTrackDiv);
-  aElements.MaybeAppendElement(mProgressDiv);
-  aElements.MaybeAppendElement(mThumbDiv);
+  if (mTrackDiv) {
+    aElements.AppendElement(mTrackDiv);
+  }
+
+  if (mProgressDiv) {
+    aElements.AppendElement(mProgressDiv);
+  }
+
+  if (mThumbDiv) {
+    aElements.AppendElement(mThumbDiv);
+  }
 }
 
 class nsDisplayRangeFocusRing : public nsDisplayItem
 {
 public:
   nsDisplayRangeFocusRing(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
     : nsDisplayItem(aBuilder, aFrame) {
     MOZ_COUNT_CTOR(nsDisplayRangeFocusRing);
--- a/layout/forms/nsRangeFrame.h
+++ b/layout/forms/nsRangeFrame.h
@@ -59,17 +59,17 @@ public:
   virtual bool IsLeaf() const MOZ_OVERRIDE { return true; }
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
   virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
                                     nsIAtom* aAttribute,
                                     int32_t  aModType) MOZ_OVERRIDE;
 
   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                  nsSize aCBSize, nscoord aAvailableWidth,
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -389,25 +389,30 @@ nsTextControlFrame::CreateAnonymousConte
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   return NS_OK;
 }
 
 void
-nsTextControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+nsTextControlFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                              uint32_t aFilter)
 {
   nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
   NS_ASSERTION(txtCtrl, "Content not a text control element");
 
-  aElements.MaybeAppendElement(txtCtrl->GetRootEditorNode());
-  if (!(aFilter & nsIContent::eSkipPlaceholderContent))
-    aElements.MaybeAppendElement(txtCtrl->GetPlaceholderNode());
+  nsIContent* root = txtCtrl->GetRootEditorNode();
+  if (root) {
+    aElements.AppendElement(root);
+  }
+
+  nsIContent* placeholder = txtCtrl->GetPlaceholderNode();
+  if (placeholder && !(aFilter & nsIContent::eSkipPlaceholderContent))
+    aElements.AppendElement(placeholder);
   
 }
 
 nscoord
 nsTextControlFrame::GetPrefISize(nsRenderingContext* aRenderingContext)
 {
     DebugOnly<nscoord> result = 0;
     DISPLAY_PREF_WIDTH(this, result);
--- a/layout/forms/nsTextControlFrame.h
+++ b/layout/forms/nsTextControlFrame.h
@@ -77,17 +77,17 @@ public:
     // nsStackFrame is already both of these, but that's somewhat bogus,
     // and we really mean it.
     return nsContainerFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
   virtual void SetInitialChildList(ChildListID     aListID,
                                    nsFrameList&    aChildList) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -109,21 +109,29 @@ nsCanvasFrame::CreateAnonymousContent(ns
                                              true);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 void
-nsCanvasFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, uint32_t aFilter)
+nsCanvasFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, uint32_t aFilter)
 {
-  aElements.MaybeAppendElement(mTouchCaretElement);
-  aElements.MaybeAppendElement(mSelectionCaretsStartElement);
-  aElements.MaybeAppendElement(mSelectionCaretsEndElement);
+  if (mTouchCaretElement) {
+    aElements.AppendElement(mTouchCaretElement);
+  }
+
+  if (mSelectionCaretsStartElement) {
+    aElements.AppendElement(mSelectionCaretsStartElement);
+  }
+
+  if (mSelectionCaretsEndElement) {
+    aElements.AppendElement(mSelectionCaretsEndElement);
+  }
 }
 
 void
 nsCanvasFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   nsIScrollableFrame* sf =
     PresContext()->GetPresShell()->GetRootScrollFrameAsScrollable();
   if (sf) {
--- a/layout/generic/nsCanvasFrame.h
+++ b/layout/generic/nsCanvasFrame.h
@@ -63,17 +63,17 @@ public:
   virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsContainerFrame::IsFrameOfType(aFlags &
              ~(nsIFrame::eCanContainOverflowContainers));
   }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, uint32_t aFilter) MOZ_OVERRIDE;
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, uint32_t aFilter) MOZ_OVERRIDE;
 
   // Touch caret handle function
   mozilla::dom::Element* GetTouchCaretElement() const
   {
      return mTouchCaretElement;
   }
 
   // Selection Caret Handle function
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -99,17 +99,17 @@ nsHTMLScrollFrame::ScrollbarActivityStop
 
 nsresult
 nsHTMLScrollFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
 {
   return mHelper.CreateAnonymousContent(aElements);
 }
 
 void
-nsHTMLScrollFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+nsHTMLScrollFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                             uint32_t aFilter)
 {
   mHelper.AppendAnonymousContentTo(aElements, aFilter);
 }
 
 void
 nsHTMLScrollFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
@@ -1043,17 +1043,17 @@ ScrollFrameHelper::WantAsyncScroll() con
 
 nsresult
 nsXULScrollFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
 {
   return mHelper.CreateAnonymousContent(aElements);
 }
 
 void
-nsXULScrollFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+nsXULScrollFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                            uint32_t aFilter)
 {
   mHelper.AppendAnonymousContentTo(aElements, aFilter);
 }
 
 void
 nsXULScrollFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
@@ -3541,23 +3541,34 @@ ScrollFrameHelper::CreateAnonymousConten
     if (!aElements.AppendElement(mScrollCornerContent))
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
 
 void
-ScrollFrameHelper::AppendAnonymousContentTo(nsBaseContentList& aElements,
+ScrollFrameHelper::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                                 uint32_t aFilter)
 {
-  aElements.MaybeAppendElement(mHScrollbarContent);
-  aElements.MaybeAppendElement(mVScrollbarContent);
-  aElements.MaybeAppendElement(mScrollCornerContent);
-  aElements.MaybeAppendElement(mResizerContent);
+  if (mHScrollbarContent) {
+    aElements.AppendElement(mHScrollbarContent);
+  }
+
+  if (mVScrollbarContent) {
+    aElements.AppendElement(mVScrollbarContent);
+  }
+
+  if (mScrollCornerContent) {
+    aElements.AppendElement(mScrollCornerContent);
+  }
+
+  if (mResizerContent) {
+    aElements.AppendElement(mResizerContent);
+  }
 }
 
 void
 ScrollFrameHelper::Destroy()
 {
   if (mScrollbarActivity) {
     mScrollbarActivity->Destroy();
     mScrollbarActivity = nullptr;
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -53,17 +53,17 @@ public:
 
   // 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<nsIAnonymousContentCreator::ContentInfo>& aElements);
-  void AppendAnonymousContentTo(nsBaseContentList& aElements, uint32_t aFilter);
+  void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, uint32_t aFilter);
   nsresult FireScrollPortEvent();
   void PostOverflowEvent();
   void Destroy();
 
   void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                         const nsRect&           aDirtyRect,
                         const nsDisplayListSet& aLists);
 
@@ -539,17 +539,17 @@ public:
   virtual nsPoint GetPositionOfChildIgnoringScrolling(nsIFrame* aChild) MOZ_OVERRIDE
   { nsPoint pt = aChild->GetPosition();
     if (aChild == mHelper.GetScrolledFrame()) pt += GetScrollPosition();
     return pt;
   }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
   // nsIScrollbarOwner
   virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE {
     return mHelper.GetScrollbarBox(aVertical);
   }
 
   virtual void ScrollbarActivityStarted() const MOZ_OVERRIDE;
@@ -828,17 +828,17 @@ public:
   { nsPoint pt = aChild->GetPosition();
     if (aChild == mHelper.GetScrolledFrame())
       pt += mHelper.GetLogicalScrollPosition();
     return pt;
   }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
   virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
 
   NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
--- a/layout/generic/nsIAnonymousContentCreator.h
+++ b/layout/generic/nsIAnonymousContentCreator.h
@@ -64,17 +64,17 @@ public:
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements)=0;
 
   /**
    * Appends "native" anonymous children created by CreateAnonymousContent()
    * to the given content list depending on the filter.
    *
    * @see nsIContent::GetChildren for set of values used for filter.
    */
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) = 0;
 
   /**
    * Implementations can override this method to create special frames for the
    * anonymous content returned from CreateAnonymousContent.
    * By default this method returns nullptr, which means the default frame
    * is created.
    */
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -116,22 +116,30 @@ 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(nsTArray<nsIContent*>& aElements,
                                        uint32_t aFliter)
 {
-  aElements.MaybeAppendElement(mPosterImage);
-  aElements.MaybeAppendElement(mVideoControls);
-  aElements.MaybeAppendElement(mCaptionDiv);
+  if (mPosterImage) {
+    aElements.AppendElement(mPosterImage);
+  }
+
+  if (mVideoControls) {
+    aElements.AppendElement(mVideoControls);
+  }
+
+  if (mCaptionDiv) {
+    aElements.AppendElement(mCaptionDiv);
+  }
 }
 
 void
 nsVideoFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   nsContentUtils::DestroyAnonymousContent(&mCaptionDiv);
   nsContentUtils::DestroyAnonymousContent(&mVideoControls);
   nsContentUtils::DestroyAnonymousContent(&mPosterImage);
--- a/layout/generic/nsVideoFrame.h
+++ b/layout/generic/nsVideoFrame.h
@@ -71,17 +71,17 @@ public:
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
   virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsSplittableFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced));
   }
   
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilters) MOZ_OVERRIDE;
 
   nsIContent* GetPosterImage() { return mPosterImage; }
 
   // Returns true if we should display the poster. Note that once we show
   // a video frame, the poster will never be displayed again.
   bool ShouldDisplayPoster();
 
--- a/layout/svg/nsSVGUseFrame.cpp
+++ b/layout/svg/nsSVGUseFrame.cpp
@@ -59,17 +59,17 @@ public:
 #endif
 
   // nsISVGChildFrame interface:
   virtual void ReflowSVG() MOZ_OVERRIDE;
   virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE;
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
 private:
   bool mHasValidDimensions;
 };
 
 //----------------------------------------------------------------------
 // Implementation
@@ -238,15 +238,17 @@ 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(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter)
 {
   SVGUseElement *use = static_cast<SVGUseElement*>(mContent);
   nsIContent* clone = use->GetAnonymousContent();
-  aElements.MaybeAppendElement(clone);
+  if (clone) {
+    aElements.AppendElement(clone);
+  }
 }
--- a/layout/xul/nsDocElementBoxFrame.cpp
+++ b/layout/xul/nsDocElementBoxFrame.cpp
@@ -38,17 +38,17 @@ public:
   nsDocElementBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext)
     :nsBoxFrame(aShell, aContext, true) {}
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
-  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
   virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     // Override nsBoxFrame.
     if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced))
       return false;
     return nsBoxFrame::IsFrameOfType(aFlags);
@@ -118,21 +118,26 @@ nsDocElementBoxFrame::CreateAnonymousCon
 
   if (!aElements.AppendElement(mTooltipContent))
     return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
 
 void
-nsDocElementBoxFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+nsDocElementBoxFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                                uint32_t aFilter)
 {
-  aElements.MaybeAppendElement(mPopupgroupContent);
-  aElements.MaybeAppendElement(mTooltipContent);
+  if (mPopupgroupContent) {
+    aElements.AppendElement(mPopupgroupContent);
+  }
+
+  if (mTooltipContent) {
+    aElements.AppendElement(mTooltipContent);
+  }
 }
 
 NS_QUERYFRAME_HEAD(nsDocElementBoxFrame)
   NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
 NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
 
 #ifdef DEBUG_FRAME_DUMP
 nsresult