LCOV - code coverage report
Current view: top level - layout/base - nsCSSFrameConstructor.h (source / functions) Hit Total Coverage
Test: output.info Lines: 108 142 76.1 %
Date: 2017-07-14 16:53:18 Functions: 43 54 79.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : /*
       7             :  * construction of a frame tree that is nearly isomorphic to the content
       8             :  * tree and updating of that tree in response to dynamic changes
       9             :  */
      10             : 
      11             : #ifndef nsCSSFrameConstructor_h___
      12             : #define nsCSSFrameConstructor_h___
      13             : 
      14             : #include "mozilla/Attributes.h"
      15             : #include "mozilla/LinkedList.h"
      16             : #include "mozilla/RestyleManager.h"
      17             : #include "mozilla/RestyleManager.h"
      18             : 
      19             : #include "nsCOMPtr.h"
      20             : #include "nsILayoutHistoryState.h"
      21             : #include "nsQuoteList.h"
      22             : #include "nsCounterManager.h"
      23             : #include "nsIAnonymousContentCreator.h"
      24             : #include "nsFrameManager.h"
      25             : #include "ScrollbarStyles.h"
      26             : 
      27             : struct nsFrameItems;
      28             : class nsStyleContext;
      29             : struct nsStyleDisplay;
      30             : struct nsGenConInitializer;
      31             : 
      32             : class nsContainerFrame;
      33             : class nsFirstLineFrame;
      34             : class nsFirstLetterFrame;
      35             : class nsICSSAnonBoxPseudo;
      36             : class nsIDocument;
      37             : class nsPageContentFrame;
      38             : struct PendingBinding;
      39             : class nsGenericDOMDataNode;
      40             : 
      41             : class nsFrameConstructorState;
      42             : 
      43             : namespace mozilla {
      44             : 
      45             : namespace dom {
      46             : 
      47             : class FlattenedChildIterator;
      48             : 
      49             : } // namespace dom
      50             : } // namespace mozilla
      51             : 
      52             : class nsCSSFrameConstructor final : public nsFrameManager
      53             : {
      54             : public:
      55             :   typedef mozilla::CSSPseudoElementType CSSPseudoElementType;
      56             :   typedef mozilla::dom::Element Element;
      57             : 
      58             :   friend class mozilla::RestyleManager;
      59             :   friend class mozilla::GeckoRestyleManager;
      60             :   friend class mozilla::ServoRestyleManager;
      61             : 
      62             :   nsCSSFrameConstructor(nsIDocument* aDocument, nsIPresShell* aPresShell);
      63           8 :   ~nsCSSFrameConstructor() {
      64           4 :     MOZ_ASSERT(mUpdateCount == 0, "Dying in the middle of our own update?");
      65           4 :   }
      66             : 
      67             :   // get the alternate text for a content node
      68             :   static void GetAlternateTextFor(nsIContent*    aContent,
      69             :                                   nsIAtom*       aTag,  // content object's tag
      70             :                                   nsXPIDLString& aAltText);
      71             : 
      72             : private:
      73             :   nsCSSFrameConstructor(const nsCSSFrameConstructor& aCopy) = delete;
      74             :   nsCSSFrameConstructor& operator=(const nsCSSFrameConstructor& aCopy) = delete;
      75             : 
      76             : public:
      77        1314 :   mozilla::RestyleManager* RestyleManager() const
      78        1314 :     { return mPresShell->GetPresContext()->RestyleManager(); }
      79             : 
      80             :   nsIFrame* ConstructRootFrame();
      81             : 
      82             :   void ReconstructDocElementHierarchy();
      83             : 
      84             :   // Create frames for content nodes that are marked as needing frames. This
      85             :   // should be called before ProcessPendingRestyles.
      86             :   // Note: It's the caller's responsibility to make sure to wrap a
      87             :   // CreateNeededFrames call in a view update batch and a script blocker.
      88             :   void CreateNeededFrames();
      89             : 
      90             : private:
      91             :   void CreateNeededFrames(nsIContent* aContent,
      92             :                           TreeMatchContext& aTreeMatchContext);
      93             : 
      94             :   enum Operation {
      95             :     CONTENTAPPEND,
      96             :     CONTENTINSERT
      97             :   };
      98             : 
      99             :   // aChild is the child being inserted for inserts, and the first
     100             :   // child being appended for appends.
     101             :   bool MaybeConstructLazily(Operation aOperation,
     102             :                               nsIContent* aContainer,
     103             :                               nsIContent* aChild);
     104             : 
     105             :   // Issues a single ContentInserted for each child of aContainer in the range
     106             :   // [aStartChild, aEndChild).
     107             :   void IssueSingleInsertNofications(nsIContent* aContainer,
     108             :                                     nsIContent* aStartChild,
     109             :                                     nsIContent* aEndChild,
     110             :                                     bool aAllowLazyConstruction,
     111             :                                     bool aForReconstruction);
     112             : 
     113             :   /**
     114             :    * Data that represents an insertion point for some child content.
     115             :    */
     116             :   struct InsertionPoint
     117             :   {
     118          29 :     InsertionPoint()
     119          29 :       : mParentFrame(nullptr), mContainer(nullptr), mMultiple(false) {}
     120         344 :     InsertionPoint(nsContainerFrame* aParentFrame, nsIContent* aContainer,
     121             :                    bool aMultiple = false)
     122         344 :       : mParentFrame(aParentFrame), mContainer(aContainer),
     123         344 :         mMultiple(aMultiple) {}
     124             :     /**
     125             :      * The parent frame to use if the inserted children needs to create
     126             :      * frame(s).  May be null, which signals that  we shouldn't try to
     127             :      * create frames for the inserted children; either because there are
     128             :      * no parent frame or because there are multiple insertion points and
     129             :      * we will call IssueSingleInsertNofications for each child instead.
     130             :      * mContainer should not be used when mParentFrame is null.
     131             :      */
     132             :     nsContainerFrame* mParentFrame;
     133             :     /**
     134             :      * The flattened tree parent for the inserted children.
     135             :      * It's undefined if mParentFrame is null.
     136             :      */
     137             :     nsIContent* mContainer;
     138             :     /**
     139             :      * If true then there are multiple insertion points, which means consumers
     140             :      * should insert children individually into the node's flattened tree parent.
     141             :      */
     142             :     bool mMultiple;
     143             :   };
     144             :   /**
     145             :    * Checks if the children of aContainer in the range [aStartChild, aEndChild)
     146             :    * can be inserted/appended to one insertion point together. If so, returns
     147             :    * that insertion point. If not, returns with InsertionPoint.mFrame == nullptr
     148             :    * and issues single ContentInserted calls for each child.
     149             :    * aEndChild = nullptr indicates that we are dealing with an append.
     150             :    */
     151             :   InsertionPoint GetRangeInsertionPoint(nsIContent* aContainer,
     152             :                                         nsIContent* aStartChild,
     153             :                                         nsIContent* aEndChild,
     154             :                                         bool aAllowLazyConstruction,
     155             :                                         bool aForReconstruction);
     156             : 
     157             :   // Returns true if parent was recreated due to frameset child, false otherwise.
     158             :   bool MaybeRecreateForFrameset(nsIFrame* aParentFrame,
     159             :                                   nsIContent* aStartChild,
     160             :                                   nsIContent* aEndChild);
     161             : 
     162             :   /**
     163             :    * For each child in the aStartChild/aEndChild range, calls
     164             :    * NoteDirtyDescendantsForServo on their flattened tree parents.  This is
     165             :    * used when content is inserted into the document and we decide that
     166             :    * we can do lazy frame construction.  It handles children being rebound to
     167             :    * different insertion points by calling NoteDirtyDescendantsForServo on each
     168             :    * child's flattened tree parent.  Only used when we are styled by Servo.
     169             :    */
     170             :   void LazilyStyleNewChildRange(nsIContent* aStartChild, nsIContent* aEndChild);
     171             : 
     172             :   /**
     173             :    * For each child in the aStartChild/aEndChild range, calls StyleNewChildren
     174             :    * on their flattened tree parents.  This is used when content is inserted
     175             :    * into the document and we decide that we cannot do lazy frame construction.
     176             :    * It handles children being rebound to different insertion points by calling
     177             :    * StyleNewChildren on each child's flattened tree parent.  Only used when we
     178             :    * are styled by Servo.
     179             :    */
     180             :   void StyleNewChildRange(nsIContent* aStartChild, nsIContent* aEndChild);
     181             : 
     182             :   /**
     183             :    * Calls StyleSubtreeForReconstruct on each child in the aStartChild/aEndChild
     184             :    * range. Only used when we are styled by Servo.
     185             :    */
     186             :   void StyleChildRangeForReconstruct(nsIContent* aStartChild,
     187             :                                      nsIContent* aEndChild);
     188             : 
     189             : public:
     190             :   /**
     191             :    * Lazy frame construction is controlled by the aAllowLazyConstruction bool
     192             :    * parameter of nsCSSFrameConstructor::ContentAppended/Inserted. It is true
     193             :    * for all inserts/appends as passed from the presshell, except for the
     194             :    * insert of the root element, which is always non-lazy. Even if the
     195             :    * aAllowLazyConstruction passed to ContentAppended/Inserted is true we still
     196             :    * may not be able to construct lazily, so we call MaybeConstructLazily.
     197             :    * MaybeConstructLazily does not allow lazy construction if any of the
     198             :    * following are true:
     199             :    *  -we are in chrome
     200             :    *  -the container is in a native anonymous subtree
     201             :    *  -the container is XUL
     202             :    *  -is any of the appended/inserted nodes are XUL or editable
     203             :    *  -(for inserts) the child is anonymous.  In the append case this function
     204             :    *   must not be called with anonymous children.
     205             :    * The XUL and chrome checks are because XBL bindings only get applied at
     206             :    * frame construction time and some things depend on the bindings getting
     207             :    * attached synchronously. The editable checks are because the editor seems
     208             :    * to expect frames to be constructed synchronously.
     209             :    *
     210             :    * If MaybeConstructLazily returns false we construct as usual, but if it
     211             :    * returns true then it adds NODE_NEEDS_FRAME bits to the newly
     212             :    * inserted/appended nodes and adds NODE_DESCENDANTS_NEED_FRAMES bits to the
     213             :    * container and up along the parent chain until it hits the root or another
     214             :    * node with that bit set. Then it posts a restyle event to ensure that a
     215             :    * flush happens to construct those frames.
     216             :    *
     217             :    * When the flush happens the presshell calls
     218             :    * nsCSSFrameConstructor::CreateNeededFrames. CreateNeededFrames follows any
     219             :    * nodes with NODE_DESCENDANTS_NEED_FRAMES set down the content tree looking
     220             :    * for nodes with NODE_NEEDS_FRAME set. It calls ContentAppended for any runs
     221             :    * of nodes with NODE_NEEDS_FRAME set that are at the end of their childlist,
     222             :    * and ContentRangeInserted for any other runs that aren't.
     223             :    *
     224             :    * If a node is removed from the document then we don't bother unsetting any
     225             :    * of the lazy bits that might be set on it, its descendants, or any of its
     226             :    * ancestor nodes because that is a slow operation, the work might be wasted
     227             :    * if another node gets inserted in its place, and we can clear the bits
     228             :    * quicker by processing the content tree from top down the next time we call
     229             :    * CreateNeededFrames. (We do clear the bits when BindToTree is called on any
     230             :    * nsIContent; so any nodes added to the document will not have any lazy bits
     231             :    * set.)
     232             :    */
     233             : 
     234             :   // If aAllowLazyConstruction is true then frame construction of the new
     235             :   // children can be done lazily.
     236             :   //
     237             :   // When constructing frames lazily, we can keep the tree match context in a
     238             :   // much easier way than nsFrameConstructorState, and thus, we're allowed to
     239             :   // provide a TreeMatchContext to avoid calling InitAncestors repeatedly deep
     240             :   // in the DOM.
     241          56 :   void ContentAppended(nsIContent* aContainer,
     242             :                        nsIContent* aFirstNewContent,
     243             :                        bool aAllowLazyConstruction,
     244             :                        TreeMatchContext* aProvidedTreeMatchContext = nullptr)
     245             :   {
     246          56 :     ContentAppended(aContainer, aFirstNewContent, aAllowLazyConstruction, false,
     247          56 :                     aProvidedTreeMatchContext);
     248          56 :   }
     249             : 
     250             :   // If aAllowLazyConstruction is true then frame construction of the new child
     251             :   // can be done lazily.
     252             :   void ContentInserted(nsIContent* aContainer,
     253             :                        nsIContent* aChild,
     254             :                        nsILayoutHistoryState* aFrameState,
     255             :                        bool aAllowLazyConstruction);
     256             : 
     257             :   // Like ContentInserted but handles inserting the children of aContainer in
     258             :   // the range [aStartChild, aEndChild).  aStartChild must be non-null.
     259             :   // aEndChild may be null to indicate the range includes all kids after
     260             :   // aStartChild.
     261             :   //
     262             :   // If aAllowLazyConstruction is true then frame construction of
     263             :   // the new children can be done lazily. It is only allowed to be true when
     264             :   // inserting a single node.
     265             :   //
     266             :   // See ContentAppended to see why we allow passing an already initialized
     267             :   // TreeMatchContext.
     268          43 :   void ContentRangeInserted(nsIContent* aContainer,
     269             :                             nsIContent* aStartChild,
     270             :                             nsIContent* aEndChild,
     271             :                             nsILayoutHistoryState* aFrameState,
     272             :                             bool aAllowLazyConstruction,
     273             :                             TreeMatchContext* aProvidedTreeMatchContext = nullptr)
     274             :   {
     275          43 :     ContentRangeInserted(aContainer, aStartChild, aEndChild, aFrameState,
     276             :                          aAllowLazyConstruction, false,
     277          43 :                          aProvidedTreeMatchContext);
     278          43 :   }
     279             : 
     280             : private:
     281             :   // Helpers for the public ContentAppended, ContentInserted and
     282             :   // ContentRangeInserted functions above.
     283             :   //
     284             :   // aForReconstruction indicates whether this call is for frame reconstruction
     285             :   // via RecreateFramesFor or lazy frame construction via CreateNeededFrames.
     286             :   // (This latter case admittedly isn't always for "reconstruction" per se, but
     287             :   // the important thing is that aForReconstruction is false for real content
     288             :   // insertions, and true for other cases.)
     289             :   void ContentAppended(nsIContent* aContainer,
     290             :                        nsIContent* aFirstNewContent,
     291             :                        bool aAllowLazyConstruction,
     292             :                        bool aForReconstruction,
     293             :                        TreeMatchContext* aProvidedTreeMatchContext);
     294             :   void ContentRangeInserted(nsIContent* aContainer,
     295             :                             nsIContent* aStartChild,
     296             :                             nsIContent* aEndChild,
     297             :                             nsILayoutHistoryState* aFrameState,
     298             :                             bool aAllowLazyConstruction,
     299             :                             bool aForReconstruction,
     300             :                             TreeMatchContext* aProvidedTreeMatchContext);
     301             : 
     302             : public:
     303             :   enum RemoveFlags {
     304             :     REMOVE_CONTENT, REMOVE_FOR_RECONSTRUCTION, REMOVE_DESTROY_FRAMES };
     305             :   /**
     306             :    * Recreate or destroy frames for aChild in aContainer.
     307             :    * aFlags == REMOVE_CONTENT means aChild has been removed from the document.
     308             :    * aFlags == REMOVE_FOR_RECONSTRUCTION means the caller will reconstruct the
     309             :    *   frames later.
     310             :    * In both the above cases, this method will in some cases try to reconstruct
     311             :    * the frames (aDidReconstruct is then set to true), it's just that in the
     312             :    * former case aChild isn't in the document so no frames will be created for
     313             :    * it.  Ancestors may have been reframed though.
     314             :    * aFlags == REMOVE_DESTROY_FRAMES is the same as REMOVE_FOR_RECONSTRUCTION
     315             :    * except it will never try to reconstruct frames.  Instead, the caller is
     316             :    * responsible for doing that, on the content returned in aDestroyedFramesFor.
     317             :    * The layout frame state is guarranted to be captured for the removed frames
     318             :    * only when aFlags == REMOVE_DESTROY_FRAMES, otherwise it will only be
     319             :    * captured if we reconstructed frames for an ancestor.
     320             :    */
     321             :   void ContentRemoved(nsIContent*  aContainer,
     322             :                       nsIContent*  aChild,
     323             :                       nsIContent*  aOldNextSibling,
     324             :                       RemoveFlags  aFlags,
     325             :                       bool*        aDidReconstruct,
     326             :                       nsIContent** aDestroyedFramesFor = nullptr);
     327             : 
     328             :   void CharacterDataChanged(nsIContent* aContent,
     329             :                             CharacterDataChangeInfo* aInfo);
     330             : 
     331             :   // If aContent is a text node that has been optimized away due to being
     332             :   // whitespace next to a block boundary (or for some other reason), stop
     333             :   // doing that and create a frame for it if it should have one. This recreates
     334             :   // frames so be careful (although this should not change actual layout).
     335             :   // Returns the frame for aContent if there is one.
     336             :   nsIFrame* EnsureFrameForTextNode(nsGenericDOMDataNode* aContent);
     337             : 
     338             :   // Generate the child frames and process bindings
     339             :   void GenerateChildFrames(nsContainerFrame* aFrame);
     340             : 
     341             :   // Should be called when a frame is going to be destroyed and
     342             :   // WillDestroyFrameTree hasn't been called yet.
     343             :   void NotifyDestroyingFrame(nsIFrame* aFrame);
     344             : 
     345             :   void BeginUpdate();
     346             :   void EndUpdate();
     347             :   void RecalcQuotesAndCounters();
     348             : 
     349             :   // Called when any counter style is changed.
     350             :   void NotifyCounterStylesAreDirty();
     351             : 
     352             :   // Gets called when the presshell is destroying itself and also
     353             :   // when we tear down our frame tree to reconstruct it
     354             :   void WillDestroyFrameTree();
     355             : 
     356             :   /**
     357             :    * Destroy the frames for aContent.  Note that this may destroy frames
     358             :    * for an ancestor instead - aDestroyedFramesFor contains the content node
     359             :    * where frames were actually destroyed (which should be used in the
     360             :    * ContentInserted call to recreate frames).  The frame tree state
     361             :    * is captured before the frames are destroyed and can be retrieved using
     362             :    * GetLastCapturedLayoutHistoryState().
     363             :    */
     364             :   void DestroyFramesFor(nsIContent*  aContent,
     365             :                         nsIContent** aDestroyedFramesFor);
     366             : 
     367             :   // Request to create a continuing frame.  This method never returns null.
     368             :   nsIFrame* CreateContinuingFrame(nsPresContext*    aPresContext,
     369             :                                   nsIFrame*         aFrame,
     370             :                                   nsContainerFrame* aParentFrame,
     371             :                                   bool              aIsFluid = true);
     372             : 
     373             :   // Copy over fixed frames from aParentFrame's prev-in-flow
     374             :   nsresult ReplicateFixedFrames(nsPageContentFrame* aParentFrame);
     375             : 
     376             :   /**
     377             :    * Get the XBL insertion point for aChild in aContainer.
     378             :    */
     379             :   InsertionPoint GetInsertionPoint(nsIContent* aContainer, nsIContent* aChild);
     380             : 
     381             :   void CreateListBoxContent(nsContainerFrame* aParentFrame,
     382             :                             nsIFrame*         aPrevFrame,
     383             :                             nsIContent*       aChild,
     384             :                             nsIFrame**        aResult,
     385             :                             bool              aIsAppend);
     386             : 
     387             :   // GetInitialContainingBlock() is deprecated in favor of GetRootElementFrame();
     388             :   // nsIFrame* GetInitialContainingBlock() { return mRootElementFrame; }
     389             :   // This returns the outermost frame for the root element
     390          53 :   nsContainerFrame* GetRootElementFrame() { return mRootElementFrame; }
     391             :   // This returns the frame for the root element that does not
     392             :   // have a psuedo-element style
     393         616 :   nsIFrame* GetRootElementStyleFrame() { return mRootElementStyleFrame; }
     394           0 :   nsIFrame* GetPageSequenceFrame() { return mPageSequenceFrame; }
     395             : 
     396             :   // Get the frame that is the parent of the root element.
     397         456 :   nsContainerFrame* GetDocElementContainingBlock()
     398         456 :     { return mDocElementContainingBlock; }
     399             : 
     400             :   /**
     401             :    * Return the layout history state that was captured in the last
     402             :    * ContentRemoved / RecreateFramesForContent call.
     403             :    */
     404           0 :   nsILayoutHistoryState* GetLastCapturedLayoutHistoryState()
     405             :   {
     406           0 :     return mTempFrameTreeState;
     407             :   }
     408             : 
     409             : private:
     410             :   struct FrameConstructionItem;
     411             :   class FrameConstructionItemList;
     412             : 
     413             :   nsContainerFrame* ConstructPageFrame(nsIPresShell*      aPresShell,
     414             :                                        nsContainerFrame*  aParentFrame,
     415             :                                        nsIFrame*          aPrevPageFrame,
     416             :                                        nsContainerFrame*& aCanvasFrame);
     417             : 
     418             :   void InitAndRestoreFrame (const nsFrameConstructorState& aState,
     419             :                             nsIContent*                    aContent,
     420             :                             nsContainerFrame*              aParentFrame,
     421             :                             nsIFrame*                      aNewFrame,
     422             :                             bool                           aAllowCounters = true);
     423             : 
     424             :   // aState can be null if not available; it's used as an optimization.
     425             :   // XXXbz IsValidSibling is the only caller that doesn't pass a state here!
     426             :   already_AddRefed<nsStyleContext>
     427             :   ResolveStyleContext(nsIFrame*                aParentFrame,
     428             :                       nsIContent*              aContainer,
     429             :                       nsIContent*              aChild,
     430             :                       nsFrameConstructorState* aState);
     431             :   already_AddRefed<nsStyleContext>
     432             :   ResolveStyleContext(nsIFrame*                aParentFrame,
     433             :                       nsIContent*              aChild,
     434             :                       nsFrameConstructorState* aState);
     435             :   already_AddRefed<nsStyleContext>
     436             :   ResolveStyleContext(const InsertionPoint&    aInsertion,
     437             :                       nsIContent*              aChild,
     438             :                       nsFrameConstructorState* aState);
     439             :   already_AddRefed<nsStyleContext>
     440             :   ResolveStyleContext(nsStyleContext*          aParentStyleContext,
     441             :                       nsIContent*              aContent,
     442             :                       nsFrameConstructorState* aState,
     443             :                       Element*                 aOriginatingElementOrNull = nullptr);
     444             : 
     445             :   // Add the frame construction items for the given aContent and aParentFrame
     446             :   // to the list.  This might add more than one item in some rare cases.
     447             :   // If aSuppressWhiteSpaceOptimizations is true, optimizations that
     448             :   // may suppress the construction of white-space-only text frames
     449             :   // must be skipped for these items and items around them.
     450             :   void AddFrameConstructionItems(nsFrameConstructorState& aState,
     451             :                                  nsIContent*              aContent,
     452             :                                  bool                     aSuppressWhiteSpaceOptimizations,
     453             :                                  const InsertionPoint&    aInsertion,
     454             :                                  FrameConstructionItemList& aItems);
     455             : 
     456             :   // Helper method for AddFrameConstructionItems etc.
     457             :   // Unsets the need-frame/restyle bits on aContent.
     458             :   // return true iff we should attempt to create frames for aContent.
     459             :   bool ShouldCreateItemsForChild(nsFrameConstructorState& aState,
     460             :                                  nsIContent* aContent,
     461             :                                  nsContainerFrame* aParentFrame);
     462             : 
     463             :   // Helper method for AddFrameConstructionItems etc.
     464             :   // Make sure ShouldCreateItemsForChild() returned true before calling this.
     465             :   void DoAddFrameConstructionItems(nsFrameConstructorState& aState,
     466             :                                    nsIContent* aContent,
     467             :                                    nsStyleContext* aStyleContext,
     468             :                                    bool aSuppressWhiteSpaceOptimizations,
     469             :                                    nsContainerFrame* aParentFrame,
     470             :                                    nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren,
     471             :                                    FrameConstructionItemList& aItems);
     472             : 
     473             :   // Construct the frames for the document element.  This can return null if the
     474             :   // document element is display:none, or if the document element has a
     475             :   // not-yet-loaded XBL binding, or if it's an SVG element that's not <svg>.
     476             :   nsIFrame* ConstructDocElementFrame(Element*                 aDocElement,
     477             :                                      nsILayoutHistoryState*   aFrameState);
     478             : 
     479             :   // Set up our mDocElementContainingBlock correctly for the given root
     480             :   // content.
     481             :   void SetUpDocElementContainingBlock(nsIContent* aDocElement);
     482             : 
     483             :   /**
     484             :    * CreateAttributeContent creates a single content/frame combination for an
     485             :    * |attr(foo)| generated content.
     486             :    *
     487             :    * @param aParentContent the parent content for the generated content
     488             :    * @param aParentFrame the parent frame for the generated frame
     489             :    * @param aAttrNamespace the namespace of the attribute in question
     490             :    * @param aAttrName the localname of the attribute
     491             :    * @param aStyleContext the style context to use
     492             :    * @param aGeneratedContent the array of generated content to append the
     493             :    *                          created content to.
     494             :    * @param [out] aNewContent the content node we create
     495             :    * @param [out] aNewFrame the new frame we create
     496             :    */
     497             :   void CreateAttributeContent(nsIContent* aParentContent,
     498             :                               nsIFrame* aParentFrame,
     499             :                               int32_t aAttrNamespace,
     500             :                               nsIAtom* aAttrName,
     501             :                               nsStyleContext* aStyleContext,
     502             :                               nsCOMArray<nsIContent>& aGeneratedContent,
     503             :                               nsIContent** aNewContent,
     504             :                               nsIFrame** aNewFrame);
     505             : 
     506             :   /**
     507             :    * Create a text node containing the given string. If aText is non-null
     508             :    * then we also set aText to the returned node.
     509             :    */
     510             :   already_AddRefed<nsIContent> CreateGenConTextNode(nsFrameConstructorState& aState,
     511             :                                                     const nsString& aString,
     512             :                                                     RefPtr<nsTextNode>* aText,
     513             :                                                     nsGenConInitializer* aInitializer);
     514             : 
     515             :   /**
     516             :    * Create a content node for the given generated content style.
     517             :    * The caller takes care of making it SetIsNativeAnonymousRoot, binding it
     518             :    * to the document, and creating frames for it.
     519             :    * @param aParentContent is the node that has the before/after style
     520             :    * @param aStyleContext is the 'before' or 'after' pseudo-element
     521             :    * style context
     522             :    * @param aContentIndex is the index of the content item to create
     523             :    */
     524             :   already_AddRefed<nsIContent> CreateGeneratedContent(nsFrameConstructorState& aState,
     525             :                                                       nsIContent*     aParentContent,
     526             :                                                       nsStyleContext* aStyleContext,
     527             :                                                       uint32_t        aContentIndex);
     528             : 
     529             :   // aFrame may be null; this method doesn't use it directly in any case.
     530             :   void CreateGeneratedContentItem(nsFrameConstructorState&   aState,
     531             :                                   nsContainerFrame*          aFrame,
     532             :                                   nsIContent*                aContent,
     533             :                                   nsStyleContext*            aStyleContext,
     534             :                                   CSSPseudoElementType       aPseudoElement,
     535             :                                   FrameConstructionItemList& aItems);
     536             : 
     537             :   // This method can change aFrameList: it can chop off the beginning and put
     538             :   // it in aParentFrame while putting the remainder into a ib-split sibling of
     539             :   // aParentFrame.  aPrevSibling must be the frame after which aFrameList is to
     540             :   // be placed on aParentFrame's principal child list.  It may be null if
     541             :   // aFrameList is being added at the beginning of the child list.
     542             :   void AppendFramesToParent(nsFrameConstructorState&       aState,
     543             :                             nsContainerFrame*              aParentFrame,
     544             :                             nsFrameItems&                  aFrameList,
     545             :                             nsIFrame*                      aPrevSibling,
     546             :                             bool                           aIsRecursiveCall = false);
     547             : 
     548             :   // BEGIN TABLE SECTION
     549             :   /**
     550             :    * Construct a table wrapper frame. This is the FrameConstructionData
     551             :    * callback used for the job.
     552             :    */
     553             :   nsIFrame* ConstructTable(nsFrameConstructorState& aState,
     554             :                            FrameConstructionItem&   aItem,
     555             :                            nsContainerFrame*        aParentFrame,
     556             :                            const nsStyleDisplay*    aDisplay,
     557             :                            nsFrameItems&            aFrameItems);
     558             : 
     559             :   /**
     560             :    * FrameConstructionData callback for constructing table rows and row groups.
     561             :    */
     562             :   nsIFrame* ConstructTableRowOrRowGroup(nsFrameConstructorState& aState,
     563             :                                         FrameConstructionItem&   aItem,
     564             :                                         nsContainerFrame*        aParentFrame,
     565             :                                         const nsStyleDisplay*    aStyleDisplay,
     566             :                                         nsFrameItems&            aFrameItems);
     567             : 
     568             :   /**
     569             :    * FrameConstructionData callback used for constructing table columns.
     570             :    */
     571             :   nsIFrame* ConstructTableCol(nsFrameConstructorState& aState,
     572             :                               FrameConstructionItem&   aItem,
     573             :                               nsContainerFrame*        aParentFrame,
     574             :                               const nsStyleDisplay*    aStyleDisplay,
     575             :                               nsFrameItems&            aFrameItems);
     576             : 
     577             :   /**
     578             :    * FrameConstructionData callback used for constructing table cells.
     579             :    */
     580             :   nsIFrame* ConstructTableCell(nsFrameConstructorState& aState,
     581             :                                FrameConstructionItem&   aItem,
     582             :                                nsContainerFrame*        aParentFrame,
     583             :                                const nsStyleDisplay*    aStyleDisplay,
     584             :                                nsFrameItems&            aFrameItems);
     585             : 
     586             : private:
     587             :   /* An enum of possible parent types for anonymous table or ruby object
     588             :      construction */
     589             :   enum ParentType {
     590             :     eTypeBlock = 0, /* This includes all non-table-related frames */
     591             :     eTypeRow,
     592             :     eTypeRowGroup,
     593             :     eTypeColGroup,
     594             :     eTypeTable,
     595             :     eTypeRuby,
     596             :     eTypeRubyBase,
     597             :     eTypeRubyBaseContainer,
     598             :     eTypeRubyText,
     599             :     eTypeRubyTextContainer,
     600             :     eParentTypeCount
     601             :   };
     602             : 
     603             :   /* 4 bits is enough to handle our ParentType values */
     604             : #define FCDATA_PARENT_TYPE_OFFSET 28
     605             :   /* Macro to get the desired parent type out of an mBits member of
     606             :      FrameConstructionData */
     607             : #define FCDATA_DESIRED_PARENT_TYPE(_bits)           \
     608             :   ParentType((_bits) >> FCDATA_PARENT_TYPE_OFFSET)
     609             :   /* Macro to create FrameConstructionData bits out of a desired parent type */
     610             : #define FCDATA_DESIRED_PARENT_TYPE_TO_BITS(_type)     \
     611             :   (((uint32_t)(_type)) << FCDATA_PARENT_TYPE_OFFSET)
     612             : 
     613             :   /* Get the parent type that aParentFrame has. */
     614        1649 :   static ParentType GetParentType(nsIFrame* aParentFrame) {
     615        1649 :     return GetParentType(aParentFrame->Type());
     616             :   }
     617             : 
     618             :   /* Get the parent type for the given LayoutFrameType */
     619             :   static ParentType GetParentType(mozilla::LayoutFrameType aFrameType);
     620             : 
     621         826 :   static bool IsRubyParentType(ParentType aParentType) {
     622         826 :     return (aParentType == eTypeRuby ||
     623         826 :             aParentType == eTypeRubyBase ||
     624         826 :             aParentType == eTypeRubyBaseContainer ||
     625        1652 :             aParentType == eTypeRubyText ||
     626         826 :             aParentType == eTypeRubyTextContainer);
     627             :   }
     628             : 
     629           0 :   static bool IsTableParentType(ParentType aParentType) {
     630           0 :     return (aParentType == eTypeTable ||
     631           0 :             aParentType == eTypeRow ||
     632           0 :             aParentType == eTypeRowGroup ||
     633           0 :             aParentType == eTypeColGroup);
     634             :   }
     635             : 
     636             :   /* A constructor function that just creates an nsIFrame object.  The caller
     637             :      is responsible for initializing the object, adding it to frame lists,
     638             :      constructing frames for the children, etc.
     639             : 
     640             :      @param nsIPresShell the presshell whose arena should be used to allocate
     641             :                          the frame.
     642             :      @param nsStyleContext the style context to use for the frame. */
     643             :   typedef nsIFrame* (* FrameCreationFunc)(nsIPresShell*, nsStyleContext*);
     644             :   typedef nsContainerFrame* (* ContainerFrameCreationFunc)(nsIPresShell*, nsStyleContext*);
     645             :   typedef nsBlockFrame* (* BlockFrameCreationFunc)(nsIPresShell*, nsStyleContext*);
     646             : 
     647             :   /* A function that can be used to get a FrameConstructionData.  Such
     648             :      a function is allowed to return null.
     649             : 
     650             :      @param nsIContent the node for which the frame is being constructed.
     651             :      @param nsStyleContext the style context to be used for the frame.
     652             :   */
     653             :   struct FrameConstructionData;
     654             :   typedef const FrameConstructionData*
     655             :     (* FrameConstructionDataGetter)(Element*, nsStyleContext*);
     656             : 
     657             :   /* A constructor function that's used for complicated construction tasks.
     658             :      This is expected to create the new frame, initialize it, add whatever
     659             :      needs to be added to aFrameItems (XXXbz is that really necessary?  Could
     660             :      caller add?  Might there be cases when the returned frame or its
     661             :      placeholder is not the thing that ends up in aFrameItems?  If not, would
     662             :      it be safe to do the add into the frame construction state after
     663             :      processing kids?  Look into this as a followup!), process children as
     664             :      needed, etc.  It is NOT expected to deal with setting the frame on the
     665             :      content.
     666             : 
     667             :      @param aState the frame construction state to use.
     668             :      @param aItem the frame construction item to use
     669             :      @param aParentFrame the frame to set as the parent of the
     670             :                          newly-constructed frame.
     671             :      @param aStyleDisplay the display struct from aItem's mStyleContext
     672             :      @param aFrameItems the frame list to add the new frame (or its
     673             :                         placeholder) to.
     674             :      @return the frame that was constructed.  This frame is what the caller
     675             :              will set as the frame on the content.  Guaranteed non-null.
     676             :   */
     677             :   typedef nsIFrame*
     678             :     (nsCSSFrameConstructor::* FrameFullConstructor)(nsFrameConstructorState& aState,
     679             :                                                     FrameConstructionItem& aItem,
     680             :                                                     nsContainerFrame* aParentFrame,
     681             :                                                     const nsStyleDisplay* aStyleDisplay,
     682             :                                                     nsFrameItems& aFrameItems);
     683             : 
     684             :   /* Bits that modify the way a FrameConstructionData is handled */
     685             : 
     686             :   /* If the FCDATA_SKIP_FRAMESET bit is set, then the frame created should not
     687             :      be set as the primary frame on the content node.  This should only be used
     688             :      in very rare cases when we create more than one frame for a given content
     689             :      node. */
     690             : #define FCDATA_SKIP_FRAMESET 0x1
     691             :   /* If the FCDATA_FUNC_IS_DATA_GETTER bit is set, then the mFunc of the
     692             :      FrameConstructionData is a getter function that can be used to get the
     693             :      actual FrameConstructionData to use. */
     694             : #define FCDATA_FUNC_IS_DATA_GETTER 0x2
     695             :   /* If the FCDATA_FUNC_IS_FULL_CTOR bit is set, then the FrameConstructionData
     696             :      has an mFullConstructor.  In this case, there is no relevant mData or
     697             :      mFunc */
     698             : #define FCDATA_FUNC_IS_FULL_CTOR 0x4
     699             :   /* If FCDATA_DISALLOW_OUT_OF_FLOW is set, do not allow the frame to
     700             :      float or be absolutely positioned.  This can also be used with
     701             :      FCDATA_FUNC_IS_FULL_CTOR to indicate what the full-constructor
     702             :      function will do. */
     703             : #define FCDATA_DISALLOW_OUT_OF_FLOW 0x8
     704             :   /* If FCDATA_FORCE_NULL_ABSPOS_CONTAINER is set, make sure to push a
     705             :      null absolute containing block before processing children for this
     706             :      frame.  If this is not set, the frame will be pushed as the
     707             :      absolute containing block as needed, based on its style */
     708             : #define FCDATA_FORCE_NULL_ABSPOS_CONTAINER 0x10
     709             :   /* If FCDATA_WRAP_KIDS_IN_BLOCKS is set, the inline kids of the frame
     710             :      will be wrapped in blocks.  This is only usable for MathML at the
     711             :      moment. */
     712             : #define FCDATA_WRAP_KIDS_IN_BLOCKS 0x20
     713             :   /* If FCDATA_SUPPRESS_FRAME is set, no frame should be created for the
     714             :      content.  If this bit is set, nothing else in the struct needs to be
     715             :      set. */
     716             : #define FCDATA_SUPPRESS_FRAME 0x40
     717             :   /* If FCDATA_MAY_NEED_SCROLLFRAME is set, the new frame should be wrapped in
     718             :      a scrollframe if its overflow type so requires. */
     719             : #define FCDATA_MAY_NEED_SCROLLFRAME 0x80
     720             : #ifdef MOZ_XUL
     721             :   /* If FCDATA_IS_POPUP is set, the new frame is a XUL popup frame.  These need
     722             :      some really weird special handling.  */
     723             : #define FCDATA_IS_POPUP 0x100
     724             : #endif /* MOZ_XUL */
     725             :   /* If FCDATA_SKIP_ABSPOS_PUSH is set, don't push this frame as an
     726             :      absolute containing block, no matter what its style says. */
     727             : #define FCDATA_SKIP_ABSPOS_PUSH 0x200
     728             :   /* If FCDATA_DISALLOW_GENERATED_CONTENT is set, then don't allow generated
     729             :      content when processing kids of this frame.  This should not be used with
     730             :      FCDATA_FUNC_IS_FULL_CTOR */
     731             : #define FCDATA_DISALLOW_GENERATED_CONTENT 0x400
     732             :   /* If FCDATA_IS_TABLE_PART is set, then the frame is some sort of
     733             :      table-related thing and we should not attempt to fetch a table-cell parent
     734             :      for it if it's inside another table-related frame. */
     735             : #define FCDATA_IS_TABLE_PART 0x800
     736             :   /* If FCDATA_IS_INLINE is set, then the frame is a non-replaced CSS
     737             :      inline box. */
     738             : #define FCDATA_IS_INLINE 0x1000
     739             :   /* If FCDATA_IS_LINE_PARTICIPANT is set, the frame is something that will
     740             :      return true for IsFrameOfType(nsIFrame::eLineParticipant) */
     741             : #define FCDATA_IS_LINE_PARTICIPANT 0x2000
     742             :   /* If FCDATA_IS_LINE_BREAK is set, the frame is something that will
     743             :      induce a line break boundary before and after itself. */
     744             : #define FCDATA_IS_LINE_BREAK 0x4000
     745             :   /* If FCDATA_ALLOW_BLOCK_STYLES is set, allow block styles when processing
     746             :      children.  This should not be used with FCDATA_FUNC_IS_FULL_CTOR. */
     747             : #define FCDATA_ALLOW_BLOCK_STYLES 0x8000
     748             :   /* If FCDATA_USE_CHILD_ITEMS is set, then use the mChildItems in the relevant
     749             :      FrameConstructionItem instead of trying to process the content's children.
     750             :      This can be used with or without FCDATA_FUNC_IS_FULL_CTOR.
     751             :      The child items might still need table pseudo processing. */
     752             : #define FCDATA_USE_CHILD_ITEMS 0x10000
     753             :   /* If FCDATA_FORCED_NON_SCROLLABLE_BLOCK is set, then this block
     754             :      would have been scrollable but has been forced to be
     755             :      non-scrollable due to being in a paginated context. */
     756             : #define FCDATA_FORCED_NON_SCROLLABLE_BLOCK 0x20000
     757             :   /* If FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, then create a
     758             :      block formatting context wrapper around the kids of this frame
     759             :      using the FrameConstructionData's mPseudoAtom for its anonymous
     760             :      box type. */
     761             : #define FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS 0x40000
     762             :   /* If FCDATA_IS_SVG_TEXT is set, then this text frame is a descendant of
     763             :      an SVG text frame. */
     764             : #define FCDATA_IS_SVG_TEXT 0x80000
     765             :   /**
     766             :    * display:contents
     767             :    */
     768             : #define FCDATA_IS_CONTENTS 0x100000
     769             :   /**
     770             :    * When FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, this bit says
     771             :    * if we should create a grid/flex/columnset container instead of
     772             :    * a block wrapper when the styles says so.
     773             :    */
     774             : #define FCDATA_ALLOW_GRID_FLEX_COLUMNSET 0x200000
     775             : 
     776             :   /* Structure representing information about how a frame should be
     777             :      constructed.  */
     778             :   struct FrameConstructionData {
     779             :     // Flag bits that can modify the way the construction happens
     780             :     uint32_t mBits;
     781             :     // We have exactly one of three types of functions, so use a union for
     782             :     // better cache locality for the ones that aren't pointer-to-member.  That
     783             :     // one needs to be separate, because we can't cast between it and the
     784             :     // others and hence wouldn't be able to initialize the union without a
     785             :     // constructor and all the resulting generated code.  See documentation
     786             :     // above for FrameCreationFunc, FrameConstructionDataGetter, and
     787             :     // FrameFullConstructor to see what the functions would do.
     788             :     union Func {
     789             :       FrameCreationFunc mCreationFunc;
     790             :       FrameConstructionDataGetter mDataGetter;
     791             :     } mFunc;
     792             :     FrameFullConstructor mFullConstructor;
     793             :     // For cases when FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, the
     794             :     // anonymous box type to use for that wrapper.
     795             :     nsICSSAnonBoxPseudo * const * const mAnonBoxPseudo;
     796             :   };
     797             : 
     798             :   /* Structure representing a mapping of an atom to a FrameConstructionData.
     799             :      This can be used with non-static atoms, assuming that the nsIAtom* is
     800             :      stored somewhere that this struct can point to (that is, a static
     801             :      nsIAtom*) and that it's allocated before the struct is ever used. */
     802             :   struct FrameConstructionDataByTag {
     803             :     // Pointer to nsIAtom* is used because we want to initialize this
     804             :     // statically, so before our atom tables are set up.
     805             :     const nsIAtom * const * const mTag;
     806             :     const FrameConstructionData mData;
     807             :   };
     808             : 
     809             :   /* Structure representing a mapping of an integer to a
     810             :      FrameConstructionData. There are no magic integer values here. */
     811             :   struct FrameConstructionDataByInt {
     812             :     /* Could be used for display or whatever else */
     813             :     const int32_t mInt;
     814             :     const FrameConstructionData mData;
     815             :   };
     816             : 
     817             :   struct FrameConstructionDataByDisplay {
     818             : #ifdef DEBUG
     819             :     const mozilla::StyleDisplay mDisplay;
     820             : #endif
     821             :     const FrameConstructionData mData;
     822             :   };
     823             : 
     824             : #ifdef DEBUG
     825             : #define FCDATA_FOR_DISPLAY(_display, _fcdata) \
     826             :   { _display, _fcdata }
     827             : #else
     828             : #define FCDATA_FOR_DISPLAY(_display, _fcdata) \
     829             :   { _fcdata }
     830             : #endif
     831             : 
     832             :   /* Structure that has a FrameConstructionData and style context pseudo-type
     833             :      for a table pseudo-frame */
     834             :   struct PseudoParentData {
     835             :     const FrameConstructionData mFCData;
     836             :     nsICSSAnonBoxPseudo * const * const mPseudoType;
     837             :   };
     838             :   /* Array of such structures that we use to properly construct table
     839             :      pseudo-frames as needed */
     840             :   static const PseudoParentData sPseudoParentData[eParentTypeCount];
     841             : 
     842             :   /* A function that takes an integer, content, style context, and array of
     843             :      FrameConstructionDataByInts and finds the appropriate frame construction
     844             :      data to use and returns it.  This can return null if none of the integers
     845             :      match or if the matching integer has a FrameConstructionDataGetter that
     846             :      returns null. */
     847             :   static const FrameConstructionData*
     848             :     FindDataByInt(int32_t aInt, Element* aElement,
     849             :                   nsStyleContext* aStyleContext,
     850             :                   const FrameConstructionDataByInt* aDataPtr,
     851             :                   uint32_t aDataLength);
     852             : 
     853             :   /* A function that takes a tag, content, style context, and array of
     854             :      FrameConstructionDataByTags and finds the appropriate frame construction
     855             :      data to use and returns it.  This can return null if none of the tags
     856             :      match or if the matching tag has a FrameConstructionDataGetter that
     857             :      returns null. */
     858             :   static const FrameConstructionData*
     859             :     FindDataByTag(nsIAtom* aTag, Element* aElement,
     860             :                   nsStyleContext* aStyleContext,
     861             :                   const FrameConstructionDataByTag* aDataPtr,
     862             :                   uint32_t aDataLength);
     863             : 
     864             :   /* A class representing a list of FrameConstructionItems */
     865             :   class FrameConstructionItemList final {
     866             :   public:
     867         926 :     FrameConstructionItemList() :
     868             :       mInlineCount(0),
     869             :       mBlockCount(0),
     870             :       mLineParticipantCount(0),
     871             :       mItemCount(0),
     872             :       mLineBoundaryAtStart(false),
     873             :       mLineBoundaryAtEnd(false),
     874             :       mParentHasNoXBLChildren(false),
     875         926 :       mTriedConstructingFrames(false)
     876             :     {
     877         926 :       memset(mDesiredParentCounts, 0, sizeof(mDesiredParentCounts));
     878         926 :     }
     879             : 
     880        2344 :     ~FrameConstructionItemList() {
     881        1418 :       while (FrameConstructionItem* item = mItems.popFirst()) {
     882         492 :         delete item;
     883         492 :       }
     884             : 
     885             :       // Create the undisplayed entries for our mUndisplayedItems, if any, but
     886             :       // only if we have tried constructing frames for this item list.  If we
     887             :       // haven't, then we're just throwing it away and will probably try again.
     888         926 :       if (!mUndisplayedItems.IsEmpty() && mTriedConstructingFrames) {
     889             :         // We could store the frame manager in a member, but just
     890             :         // getting it off the style context is not too bad.
     891             :         nsFrameManager *mgr =
     892         101 :           mUndisplayedItems[0].mStyleContext->PresContext()->FrameManager();
     893         395 :         for (uint32_t i = 0; i < mUndisplayedItems.Length(); ++i) {
     894         294 :           UndisplayedItem& item = mUndisplayedItems[i];
     895         294 :           mgr->SetUndisplayedContent(item.mContent, item.mStyleContext);
     896             :         }
     897             :       }
     898         926 :     }
     899             : 
     900          29 :     void SetLineBoundaryAtStart(bool aBoundary) { mLineBoundaryAtStart = aBoundary; }
     901          29 :     void SetLineBoundaryAtEnd(bool aBoundary) { mLineBoundaryAtEnd = aBoundary; }
     902         290 :     void SetParentHasNoXBLChildren(bool aHasNoXBLChildren) {
     903         290 :       mParentHasNoXBLChildren = aHasNoXBLChildren;
     904         290 :     }
     905         413 :     void SetTriedConstructingFrames() { mTriedConstructingFrames = true; }
     906          21 :     bool HasLineBoundaryAtStart() { return mLineBoundaryAtStart; }
     907           5 :     bool HasLineBoundaryAtEnd() { return mLineBoundaryAtEnd; }
     908           9 :     bool ParentHasNoXBLChildren() { return mParentHasNoXBLChildren; }
     909         886 :     bool IsEmpty() const { return mItems.isEmpty(); }
     910         468 :     bool AnyItemsNeedBlockParent() const { return mLineParticipantCount != 0; }
     911           0 :     bool AreAllItemsInline() const { return mInlineCount == mItemCount; }
     912           0 :     bool AreAllItemsBlock() const { return mBlockCount == mItemCount; }
     913         457 :     bool AllWantParentType(ParentType aDesiredParentType) const {
     914         457 :       return mDesiredParentCounts[aDesiredParentType] == mItemCount;
     915             :     }
     916             : 
     917             :     // aSuppressWhiteSpaceOptimizations is true if optimizations that
     918             :     // skip constructing whitespace frames for this item or items
     919             :     // around it cannot be performed.
     920             :     // Also, the return value is always non-null, thanks to infallible 'new'.
     921         492 :     FrameConstructionItem* AppendItem(const FrameConstructionData* aFCData,
     922             :                                       nsIContent* aContent,
     923             :                                       nsIAtom* aTag,
     924             :                                       int32_t aNameSpaceID,
     925             :                                       PendingBinding* aPendingBinding,
     926             :                                       already_AddRefed<nsStyleContext>&& aStyleContext,
     927             :                                       bool aSuppressWhiteSpaceOptimizations,
     928             :                                       nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren)
     929             :     {
     930             :       FrameConstructionItem* item =
     931             :         new FrameConstructionItem(aFCData, aContent, aTag, aNameSpaceID,
     932             :                                   aPendingBinding, aStyleContext,
     933             :                                   aSuppressWhiteSpaceOptimizations,
     934         492 :                                   aAnonChildren);
     935         492 :       mItems.insertBack(item);
     936         492 :       ++mItemCount;
     937         492 :       ++mDesiredParentCounts[item->DesiredParentType()];
     938         492 :       return item;
     939             :     }
     940             : 
     941             :     // Arguments are the same as AppendItem().
     942           0 :     FrameConstructionItem* PrependItem(const FrameConstructionData* aFCData,
     943             :                                        nsIContent* aContent,
     944             :                                        nsIAtom* aTag,
     945             :                                        int32_t aNameSpaceID,
     946             :                                        PendingBinding* aPendingBinding,
     947             :                                        already_AddRefed<nsStyleContext>&& aStyleContext,
     948             :                                        bool aSuppressWhiteSpaceOptimizations,
     949             :                                        nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren)
     950             :     {
     951             :       FrameConstructionItem* item =
     952             :         new FrameConstructionItem(aFCData, aContent, aTag, aNameSpaceID,
     953             :                                   aPendingBinding, aStyleContext,
     954             :                                   aSuppressWhiteSpaceOptimizations,
     955           0 :                                   aAnonChildren);
     956           0 :       mItems.insertFront(item);
     957           0 :       ++mItemCount;
     958           0 :       ++mDesiredParentCounts[item->DesiredParentType()];
     959           0 :       return item;
     960             :     }
     961             : 
     962         294 :     void AppendUndisplayedItem(nsIContent* aContent,
     963             :                                nsStyleContext* aStyleContext) {
     964         294 :       mUndisplayedItems.AppendElement(UndisplayedItem(aContent, aStyleContext));
     965         294 :     }
     966             : 
     967         198 :     void InlineItemAdded() { ++mInlineCount; }
     968         293 :     void BlockItemAdded() { ++mBlockCount; }
     969          25 :     void LineParticipantItemAdded() { ++mLineParticipantCount; }
     970             : 
     971             :     class Iterator {
     972             :     public:
     973         413 :       explicit Iterator(FrameConstructionItemList& aList)
     974         413 :         : mCurrent(aList.mItems.getFirst())
     975         413 :         , mList(aList)
     976         413 :       {}
     977           9 :       Iterator(const Iterator& aOther) :
     978           9 :         mCurrent(aOther.mCurrent),
     979           9 :         mList(aOther.mList)
     980           9 :       {}
     981             : 
     982           0 :       bool operator==(const Iterator& aOther) const {
     983           0 :         MOZ_ASSERT(&mList == &aOther.mList, "Iterators for different lists?");
     984           0 :         return mCurrent == aOther.mCurrent;
     985             :       }
     986           0 :       bool operator!=(const Iterator& aOther) const {
     987           0 :         return !(*this == aOther);
     988             :       }
     989           0 :       Iterator& operator=(const Iterator& aOther) {
     990           0 :         MOZ_ASSERT(&mList == &aOther.mList, "Iterators for different lists?");
     991           0 :         mCurrent = aOther.mCurrent;
     992           0 :         return *this;
     993             :       }
     994             : 
     995          35 :       FrameConstructionItemList* List() {
     996          35 :         return &mList;
     997             :       }
     998             : 
     999        1037 :       FrameConstructionItem& item() {
    1000        1037 :         MOZ_ASSERT(!IsDone(), "Should have checked IsDone()!");
    1001        1037 :         return *mCurrent;
    1002             :       }
    1003             : 
    1004           0 :       const FrameConstructionItem& item() const {
    1005           0 :         MOZ_ASSERT(!IsDone(), "Should have checked IsDone()!");
    1006           0 :         return *mCurrent;
    1007             :       }
    1008             : 
    1009        2448 :       bool IsDone() const { return mCurrent == nullptr; }
    1010          25 :       bool AtStart() const { return mCurrent == mList.mItems.getFirst(); }
    1011         499 :       void Next() {
    1012         499 :         NS_ASSERTION(!IsDone(), "Should have checked IsDone()!");
    1013         499 :         mCurrent = mCurrent->getNext();
    1014         499 :       }
    1015           2 :       void Prev() {
    1016           2 :         NS_ASSERTION(!AtStart(), "Should have checked AtStart()!");
    1017           2 :         mCurrent = mCurrent ? mCurrent->getPrevious() : mList.mItems.getLast();
    1018           2 :       }
    1019           0 :       void SetToEnd() { mCurrent = nullptr; }
    1020             : 
    1021             :       // Skip over all items that want the given parent type. Return whether
    1022             :       // the iterator is done after doing that.  The iterator must not be done
    1023             :       // when this is called.
    1024             :       inline bool SkipItemsWantingParentType(ParentType aParentType);
    1025             : 
    1026             :       // Skip over all items that want a parent type different from the given
    1027             :       // one.  Return whether the iterator is done after doing that.  The
    1028             :       // iterator must not be done when this is called.
    1029             :       inline bool SkipItemsNotWantingParentType(ParentType aParentType);
    1030             : 
    1031             :       // Skip over non-replaced inline frames and positioned frames.
    1032             :       // Return whether the iterator is done after doing that.
    1033             :       // The iterator must not be done when this is called.
    1034             :       inline bool SkipItemsThatNeedAnonFlexOrGridItem(
    1035             :         const nsFrameConstructorState& aState,
    1036             :         bool aIsWebkitBox);
    1037             : 
    1038             :       // Skip to the first frame that is a non-replaced inline or is
    1039             :       // positioned.  Return whether the iterator is done after doing that.
    1040             :       // The iterator must not be done when this is called.
    1041             :       inline bool SkipItemsThatDontNeedAnonFlexOrGridItem(
    1042             :         const nsFrameConstructorState& aState,
    1043             :         bool aIsWebkitBox);
    1044             : 
    1045             :       // Skip over all items that do not want a ruby parent.  Return whether
    1046             :       // the iterator is done after doing that.  The iterator must not be done
    1047             :       // when this is called.
    1048             :       inline bool SkipItemsNotWantingRubyParent();
    1049             : 
    1050             :       // Skip over whitespace.  Return whether the iterator is done after doing
    1051             :       // that.  The iterator must not be done, and must be pointing to a
    1052             :       // whitespace item when this is called.
    1053             :       inline bool SkipWhitespace(nsFrameConstructorState& aState);
    1054             : 
    1055             :       // Remove the item pointed to by this iterator from its current list and
    1056             :       // Append it to aTargetList.  This iterator is advanced to point to the
    1057             :       // next item in its list.  aIter must not be done.  aTargetList must not be
    1058             :       // the list this iterator is iterating over..
    1059             :       void AppendItemToList(FrameConstructionItemList& aTargetList);
    1060             : 
    1061             :       // As above, but moves all items starting with this iterator until we
    1062             :       // get to aEnd; the item pointed to by aEnd is not stolen.  This method
    1063             :       // might have optimizations over just looping and doing StealItem for
    1064             :       // some special cases.  After this method returns, this iterator will
    1065             :       // point to the item aEnd points to now; aEnd is not modified.
    1066             :       // aTargetList must not be the list this iterator is iterating over.
    1067             :       void AppendItemsToList(const Iterator& aEnd,
    1068             :                              FrameConstructionItemList& aTargetList);
    1069             : 
    1070             :       // Insert aItem in this iterator's list right before the item pointed to
    1071             :       // by this iterator.  After the insertion, this iterator will continue to
    1072             :       // point to the item it now points to (the one just after the
    1073             :       // newly-inserted item).  This iterator is allowed to be done; in that
    1074             :       // case this call just appends the given item to the list.
    1075             :       void InsertItem(FrameConstructionItem* aItem);
    1076             : 
    1077             :       // Delete the items between this iterator and aEnd, including the item
    1078             :       // this iterator currently points to but not including the item pointed
    1079             :       // to by aEnd.  When this returns, this iterator will point to the same
    1080             :       // item as aEnd.  This iterator must not equal aEnd when this method is
    1081             :       // called.
    1082             :       void DeleteItemsTo(const Iterator& aEnd);
    1083             : 
    1084             :     private:
    1085             :       FrameConstructionItem* mCurrent;
    1086             :       FrameConstructionItemList& mList;
    1087             :     };
    1088             : 
    1089             :   private:
    1090         882 :     struct UndisplayedItem {
    1091         294 :       UndisplayedItem(nsIContent* aContent, nsStyleContext* aStyleContext) :
    1092         294 :         mContent(aContent), mStyleContext(aStyleContext)
    1093         294 :       {}
    1094             : 
    1095             :       nsIContent * const mContent;
    1096             :       RefPtr<nsStyleContext> mStyleContext;
    1097             :     };
    1098             : 
    1099             :     // Adjust our various counts for aItem being added or removed.  aDelta
    1100             :     // should be either +1 or -1 depending on which is happening.
    1101             :     void AdjustCountsForItem(FrameConstructionItem* aItem, int32_t aDelta);
    1102             : 
    1103             :     mozilla::LinkedList<FrameConstructionItem> mItems;
    1104             :     uint32_t mInlineCount;
    1105             :     uint32_t mBlockCount;
    1106             :     uint32_t mLineParticipantCount;
    1107             :     uint32_t mItemCount;
    1108             :     uint32_t mDesiredParentCounts[eParentTypeCount];
    1109             :     // True if there is guaranteed to be a line boundary before the
    1110             :     // frames created by these items
    1111             :     bool mLineBoundaryAtStart;
    1112             :     // True if there is guaranteed to be a line boundary after the
    1113             :     // frames created by these items
    1114             :     bool mLineBoundaryAtEnd;
    1115             :     // True if the parent is guaranteed to have no XBL anonymous children
    1116             :     bool mParentHasNoXBLChildren;
    1117             :     // True if we have tried constructing frames from this list
    1118             :     bool mTriedConstructingFrames;
    1119             : 
    1120             :     nsTArray<UndisplayedItem> mUndisplayedItems;
    1121             :   };
    1122             : 
    1123             :   typedef FrameConstructionItemList::Iterator FCItemIterator;
    1124             : 
    1125             :   /* A struct representing an item for which frames might need to be
    1126             :    * constructed.  This contains all the information needed to construct the
    1127             :    * frame other than the parent frame and whatever would be stored in the
    1128             :    * frame constructor state. */
    1129             :   struct FrameConstructionItem final
    1130             :     : public mozilla::LinkedListElement<FrameConstructionItem> {
    1131         513 :     FrameConstructionItem(const FrameConstructionData* aFCData,
    1132             :                           nsIContent* aContent,
    1133             :                           nsIAtom* aTag,
    1134             :                           int32_t aNameSpaceID,
    1135             :                           PendingBinding* aPendingBinding,
    1136             :                           already_AddRefed<nsStyleContext>& aStyleContext,
    1137             :                           bool aSuppressWhiteSpaceOptimizations,
    1138         513 :                           nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren) :
    1139             :       mFCData(aFCData), mContent(aContent), mTag(aTag),
    1140             :       mPendingBinding(aPendingBinding), mStyleContext(aStyleContext),
    1141             :       mNameSpaceID(aNameSpaceID),
    1142             :       mSuppressWhiteSpaceOptimizations(aSuppressWhiteSpaceOptimizations),
    1143             :       mIsText(false), mIsGeneratedContent(false),
    1144             :       mIsAnonymousContentCreatorContent(false),
    1145             :       mIsRootPopupgroup(false), mIsAllInline(false), mIsBlock(false),
    1146             :       mHasInlineEnds(false), mIsPopup(false),
    1147         513 :       mIsLineParticipant(false), mIsForSVGAElement(false)
    1148             :     {
    1149         513 :       if (aAnonChildren) {
    1150           0 :         NS_ASSERTION(!(mFCData->mBits & FCDATA_FUNC_IS_FULL_CTOR) ||
    1151             :                      mFCData->mFullConstructor ==
    1152             :                        &nsCSSFrameConstructor::ConstructInline,
    1153             :                      "This is going to fail");
    1154           0 :         NS_ASSERTION(!(mFCData->mBits & FCDATA_USE_CHILD_ITEMS),
    1155             :                      "nsIAnonymousContentCreator::CreateAnonymousContent "
    1156             :                      "implementations should not output a list where the "
    1157             :                      "items have children in this case");
    1158           0 :         mAnonChildren.SwapElements(*aAnonChildren);
    1159             :       }
    1160         513 :     }
    1161        1026 :     ~FrameConstructionItem() {
    1162         513 :       if (mIsGeneratedContent) {
    1163           0 :         mContent->UnbindFromTree();
    1164           0 :         NS_RELEASE(mContent);
    1165             :       }
    1166         513 :     }
    1167             : 
    1168         984 :     ParentType DesiredParentType() {
    1169         984 :       return FCDATA_DESIRED_PARENT_TYPE(mFCData->mBits);
    1170             :     }
    1171             : 
    1172             :     // Indicates whether (when in a flex or grid container) this item needs
    1173             :     // to be wrapped in an anonymous block.  (Note that we implement
    1174             :     // -webkit-box/-webkit-inline-box using our standard flexbox frame class,
    1175             :     // but we use different rules for what gets wrapped. The aIsWebkitBox
    1176             :     // parameter here tells us whether to use those different rules.)
    1177             :     bool NeedsAnonFlexOrGridItem(const nsFrameConstructorState& aState,
    1178             :                                  bool aIsWebkitBox);
    1179             : 
    1180             :     // Don't call this unless the frametree really depends on the answer!
    1181             :     // Especially so for generated content, where we don't want to reframe
    1182             :     // things.
    1183             :     bool IsWhitespace(nsFrameConstructorState& aState) const;
    1184             : 
    1185           4 :     bool IsLineBoundary() const {
    1186           4 :       return mIsBlock || (mFCData->mBits & FCDATA_IS_LINE_BREAK);
    1187             :     }
    1188             : 
    1189             :     // Child frame construction items.
    1190             :     FrameConstructionItemList mChildItems;
    1191             : 
    1192             :     // ContentInfo list for children that have yet to have
    1193             :     // FrameConstructionItem objects created for them. This exists because
    1194             :     // AddFrameConstructionItemsInternal needs a valid frame, but in the case
    1195             :     // that nsIAnonymousContentCreator::CreateAnonymousContent returns items
    1196             :     // that have their own children (so we have a tree of ContentInfo objects
    1197             :     // rather than a flat list) we don't yet have a frame to provide to
    1198             :     // AddFrameConstructionItemsInternal in order to create the items for the
    1199             :     // grandchildren. That prevents FrameConstructionItems from being created
    1200             :     // for these grandchildren (and any descendants that they may have),
    1201             :     // otherwise they could have been added to the mChildItems member of their
    1202             :     // parent FrameConstructionItem. As it is, the grandchildren ContentInfo
    1203             :     // list has to be stored in this mAnonChildren member in order to delay
    1204             :     // construction of the FrameConstructionItems for the grandchildren until
    1205             :     // a frame has been created for their parent item.
    1206             :     nsTArray<nsIAnonymousContentCreator::ContentInfo> mAnonChildren;
    1207             : 
    1208             :     // The FrameConstructionData to use.
    1209             :     const FrameConstructionData* mFCData;
    1210             :     // The nsIContent node to use when initializing the new frame.
    1211             :     nsIContent* mContent;
    1212             :     // The XBL-resolved tag name to use for frame construction.
    1213             :     nsIAtom* mTag;
    1214             :     // The PendingBinding for this frame construction item, if any.  May be
    1215             :     // null.  We maintain a list of PendingBindings in the frame construction
    1216             :     // state in the order in which AddToAttachedQueue should be called on them:
    1217             :     // depth-first, post-order traversal order.  Since we actually traverse the
    1218             :     // DOM in a mix of breadth-first and depth-first, it is the responsibility
    1219             :     // of whoever constructs FrameConstructionItem kids of a given
    1220             :     // FrameConstructionItem to push its mPendingBinding as the current
    1221             :     // insertion point before doing so and pop it afterward.
    1222             :     PendingBinding* mPendingBinding;
    1223             :     // The style context to use for creating the new frame.
    1224             :     RefPtr<nsStyleContext> mStyleContext;
    1225             :     // The XBL-resolved namespace to use for frame construction.
    1226             :     int32_t mNameSpaceID;
    1227             :     // Whether optimizations to skip constructing textframes around
    1228             :     // this content need to be suppressed.
    1229             :     bool mSuppressWhiteSpaceOptimizations:1;
    1230             :     // Whether this is a text content item.
    1231             :     bool mIsText:1;
    1232             :     // Whether this is a generated content container.
    1233             :     // If it is, mContent is a strong pointer.
    1234             :     bool mIsGeneratedContent:1;
    1235             :     // Whether this is an item for nsIAnonymousContentCreator content.
    1236             :     bool mIsAnonymousContentCreatorContent:1;
    1237             :     // Whether this is an item for the root popupgroup.
    1238             :     bool mIsRootPopupgroup:1;
    1239             :     // Whether construction from this item will create only frames that are
    1240             :     // IsInlineOutside() in the principal child list.  This is not precise, but
    1241             :     // conservative: if true the frames will really be inline, whereas if false
    1242             :     // they might still all be inline.
    1243             :     bool mIsAllInline:1;
    1244             :     // Whether construction from this item will create only frames that are
    1245             :     // IsBlockOutside() in the principal child list.  This is not precise, but
    1246             :     // conservative: if true the frames will really be blocks, whereas if false
    1247             :     // they might still be blocks (and in particular, out-of-flows that didn't
    1248             :     // find a containing block).
    1249             :     bool mIsBlock:1;
    1250             :     // Whether construction from this item will give leading and trailing
    1251             :     // inline frames.  This is equal to mIsAllInline, except for inline frame
    1252             :     // items, where it's always true, whereas mIsAllInline might be false due
    1253             :     // to {ib} splits.
    1254             :     bool mHasInlineEnds:1;
    1255             :     // Whether construction from this item will create a popup that needs to
    1256             :     // go into the global popup items.
    1257             :     bool mIsPopup:1;
    1258             :     // Whether this item should be treated as a line participant
    1259             :     bool mIsLineParticipant:1;
    1260             :     // Whether this item is for an SVG <a> element
    1261             :     bool mIsForSVGAElement:1;
    1262             : 
    1263             :   private:
    1264             :     FrameConstructionItem(const FrameConstructionItem& aOther) = delete; /* not implemented */
    1265             :   };
    1266             : 
    1267             :   /**
    1268             :    * Function to create the anonymous flex or grid items that we need.
    1269             :    * If aParentFrame is not a nsFlexContainerFrame or nsGridContainerFrame then
    1270             :    * this method is a NOP.
    1271             :    * @param aItems the child frame construction items before pseudo creation
    1272             :    * @param aParentFrame the parent frame
    1273             :    */
    1274             :   void CreateNeededAnonFlexOrGridItems(nsFrameConstructorState& aState,
    1275             :                                        FrameConstructionItemList& aItems,
    1276             :                                        nsIFrame* aParentFrame);
    1277             : 
    1278             :   enum RubyWhitespaceType
    1279             :   {
    1280             :     eRubyNotWhitespace,
    1281             :     eRubyInterLevelWhitespace,
    1282             :     // Includes inter-base and inter-annotation whitespace
    1283             :     eRubyInterLeafWhitespace,
    1284             :     eRubyInterSegmentWhitespace
    1285             :   };
    1286             : 
    1287             :   /**
    1288             :    * Function to compute the whitespace type according to the display
    1289             :    * values of the previous and the next elements.
    1290             :    */
    1291             :   static inline RubyWhitespaceType ComputeRubyWhitespaceType(
    1292             :     mozilla::StyleDisplay aPrevDisplay, mozilla::StyleDisplay aNextDisplay);
    1293             : 
    1294             :   /**
    1295             :    * Function to interpret the type of whitespace between
    1296             :    * |aStartIter| and |aEndIter|.
    1297             :    */
    1298             :   static inline RubyWhitespaceType InterpretRubyWhitespace(
    1299             :     nsFrameConstructorState& aState,
    1300             :     const FCItemIterator& aStartIter, const FCItemIterator& aEndIter);
    1301             : 
    1302             :   /**
    1303             :    * Function to wrap consecutive misparented inline content into
    1304             :    * a ruby base box or a ruby text box.
    1305             :    */
    1306             :   void WrapItemsInPseudoRubyLeafBox(FCItemIterator& aIter,
    1307             :                                     nsStyleContext* aParentStyle,
    1308             :                                     nsIContent* aParentContent);
    1309             : 
    1310             :   /**
    1311             :    * Function to wrap consecutive misparented items
    1312             :    * into a ruby level container.
    1313             :    */
    1314             :   inline void WrapItemsInPseudoRubyLevelContainer(
    1315             :     nsFrameConstructorState& aState, FCItemIterator& aIter,
    1316             :     nsStyleContext* aParentStyle, nsIContent* aParentContent);
    1317             : 
    1318             :   /**
    1319             :    * Function to trim leading and trailing whitespaces.
    1320             :    */
    1321             :   inline void TrimLeadingAndTrailingWhitespaces(
    1322             :     nsFrameConstructorState& aState, FrameConstructionItemList& aItems);
    1323             : 
    1324             :   /**
    1325             :    * Function to create internal ruby boxes.
    1326             :    */
    1327             :   inline void CreateNeededPseudoInternalRubyBoxes(
    1328             :     nsFrameConstructorState& aState,
    1329             :     FrameConstructionItemList& aItems, nsIFrame* aParentFrame);
    1330             : 
    1331             :   /**
    1332             :    * Function to create the pseudo intermediate containers we need.
    1333             :    * @param aItems the child frame construction items before pseudo creation
    1334             :    * @param aParentFrame the parent frame we're creating pseudos for
    1335             :    */
    1336             :   inline void CreateNeededPseudoContainers(nsFrameConstructorState& aState,
    1337             :                                            FrameConstructionItemList& aItems,
    1338             :                                            nsIFrame* aParentFrame);
    1339             : 
    1340             :   /**
    1341             :    * Function to wrap consecutive items into a pseudo parent.
    1342             :    */
    1343             :   inline void WrapItemsInPseudoParent(nsIContent* aParentContent,
    1344             :                                       nsStyleContext* aParentStyle,
    1345             :                                       ParentType aWrapperType,
    1346             :                                       FCItemIterator& aIter,
    1347             :                                       const FCItemIterator& aEndIter);
    1348             : 
    1349             :   /**
    1350             :    * Function to create the pseudo siblings we need.
    1351             :    */
    1352             :   inline void CreateNeededPseudoSiblings(nsFrameConstructorState& aState,
    1353             :                                          FrameConstructionItemList& aItems,
    1354             :                                          nsIFrame* aParentFrame);
    1355             : 
    1356             :   /**
    1357             :    * Function to adjust aParentFrame to deal with captions.
    1358             :    * @param aParentFrame the frame we think should be the parent.  This will be
    1359             :    *        adjusted to point to the right parent frame.
    1360             :    * @param aFCData the FrameConstructionData that would be used for frame
    1361             :    *        construction.
    1362             :    * @param aStyleContext the style context for aChildContent
    1363             :    */
    1364             :   // XXXbz this function should really go away once we rework pseudo-frame
    1365             :   // handling to be better. This should simply be part of the job of
    1366             :   // GetGeometricParent, and stuff like the frameitems and parent frame should
    1367             :   // be kept track of in the state...
    1368             :   void AdjustParentFrame(nsContainerFrame**           aParentFrame,
    1369             :                          const FrameConstructionData* aFCData,
    1370             :                          nsStyleContext*              aStyleContext);
    1371             : 
    1372             :   // END TABLE SECTION
    1373             : 
    1374             : protected:
    1375             :   static nsIFrame* CreatePlaceholderFrameFor(nsIPresShell*     aPresShell,
    1376             :                                              nsIContent*       aContent,
    1377             :                                              nsIFrame*         aFrame,
    1378             :                                              nsContainerFrame* aParentFrame,
    1379             :                                              nsIFrame*         aPrevInFlow,
    1380             :                                              nsFrameState      aTypeBit);
    1381             : 
    1382             :   static nsIFrame* CreateBackdropFrameFor(nsIPresShell* aPresShell,
    1383             :                                           nsIContent* aContent,
    1384             :                                           nsIFrame* aFrame,
    1385             :                                           nsContainerFrame* aParentFrame);
    1386             : 
    1387             : private:
    1388             :   // ConstructSelectFrame puts the new frame in aFrameItems and
    1389             :   // handles the kids of the select.
    1390             :   nsIFrame* ConstructSelectFrame(nsFrameConstructorState& aState,
    1391             :                                  FrameConstructionItem&   aItem,
    1392             :                                  nsContainerFrame*        aParentFrame,
    1393             :                                  const nsStyleDisplay*    aStyleDisplay,
    1394             :                                  nsFrameItems&            aFrameItems);
    1395             : 
    1396             :   // ConstructFieldSetFrame puts the new frame in aFrameItems and
    1397             :   // handles the kids of the fieldset
    1398             :   nsIFrame* ConstructFieldSetFrame(nsFrameConstructorState& aState,
    1399             :                                    FrameConstructionItem&   aItem,
    1400             :                                    nsContainerFrame*        aParentFrame,
    1401             :                                    const nsStyleDisplay*    aStyleDisplay,
    1402             :                                    nsFrameItems&            aFrameItems);
    1403             : 
    1404             :   // ConstructDetailsFrame puts the new frame in aFrameItems and
    1405             :   // handles the kids of the details.
    1406             :   nsIFrame* ConstructDetailsFrame(nsFrameConstructorState& aState,
    1407             :                                   FrameConstructionItem& aItem,
    1408             :                                   nsContainerFrame* aParentFrame,
    1409             :                                   const nsStyleDisplay* aStyleDisplay,
    1410             :                                   nsFrameItems& aFrameItems);
    1411             : 
    1412             :   // aParentFrame might be null.  If it is, that means it was an
    1413             :   // inline frame.
    1414             :   static const FrameConstructionData* FindTextData(nsIFrame* aParentFrame);
    1415             : 
    1416             :   void ConstructTextFrame(const FrameConstructionData* aData,
    1417             :                           nsFrameConstructorState& aState,
    1418             :                           nsIContent*              aContent,
    1419             :                           nsContainerFrame*        aParentFrame,
    1420             :                           nsStyleContext*          aStyleContext,
    1421             :                           nsFrameItems&            aFrameItems);
    1422             : 
    1423             :   // If aPossibleTextContent is a text node and doesn't have a frame, append a
    1424             :   // frame construction item for it to aItems.
    1425             :   void AddTextItemIfNeeded(nsFrameConstructorState& aState,
    1426             :                            const InsertionPoint& aInsertion,
    1427             :                            nsIContent* aPossibleTextContent,
    1428             :                            FrameConstructionItemList& aItems);
    1429             : 
    1430             :   // If aParentContent's child aContent is a text node and
    1431             :   // doesn't have a frame, try to create a frame for it.
    1432             :   void ReframeTextIfNeeded(nsIContent* aParentContent,
    1433             :                            nsIContent* aContent);
    1434             : 
    1435             :   void AddPageBreakItem(nsIContent* aContent,
    1436             :                         FrameConstructionItemList& aItems);
    1437             : 
    1438             :   // Function to find FrameConstructionData for aElement.  Will return
    1439             :   // null if aElement is not HTML.
    1440             :   // aParentFrame might be null.  If it is, that means it was an
    1441             :   // inline frame.
    1442             :   static const FrameConstructionData* FindHTMLData(Element* aContent,
    1443             :                                                    nsIAtom* aTag,
    1444             :                                                    int32_t aNameSpaceID,
    1445             :                                                    nsIFrame* aParentFrame,
    1446             :                                                    nsStyleContext* aStyleContext);
    1447             :   // HTML data-finding helper functions
    1448             :   static const FrameConstructionData*
    1449             :     FindImgData(Element* aElement, nsStyleContext* aStyleContext);
    1450             :   static const FrameConstructionData*
    1451             :     FindImgControlData(Element* aElement, nsStyleContext* aStyleContext);
    1452             :   static const FrameConstructionData*
    1453             :     FindInputData(Element* aElement, nsStyleContext* aStyleContext);
    1454             :   static const FrameConstructionData*
    1455             :     FindObjectData(Element* aElement, nsStyleContext* aStyleContext);
    1456             :   static const FrameConstructionData*
    1457             :     FindCanvasData(Element* aElement, nsStyleContext* aStyleContext);
    1458             : 
    1459             :   /* Construct a frame from the given FrameConstructionItem.  This function
    1460             :      will handle adding the frame to frame lists, processing children, setting
    1461             :      the frame as the primary frame for the item's content, and so forth.
    1462             : 
    1463             :      @param aItem the FrameConstructionItem to use.
    1464             :      @param aState the frame construction state to use.
    1465             :      @param aParentFrame the frame to set as the parent of the
    1466             :                          newly-constructed frame.
    1467             :      @param aFrameItems the frame list to add the new frame (or its
    1468             :                         placeholder) to.
    1469             :   */
    1470             :   void ConstructFrameFromItemInternal(FrameConstructionItem& aItem,
    1471             :                                       nsFrameConstructorState& aState,
    1472             :                                       nsContainerFrame* aParentFrame,
    1473             :                                       nsFrameItems& aFrameItems);
    1474             : 
    1475             :   // possible flags for AddFrameConstructionItemInternal's aFlags argument
    1476             :   /* Allow xbl:base to affect the tag/namespace used. */
    1477             : #define ITEM_ALLOW_XBL_BASE 0x1
    1478             :   /* Allow page-break before and after items to be created if the
    1479             :      style asks for them. */
    1480             : #define ITEM_ALLOW_PAGE_BREAK 0x2
    1481             :   /* The item is a generated content item. */
    1482             : #define ITEM_IS_GENERATED_CONTENT 0x4
    1483             :   /* The item is within an SVG text block frame. */
    1484             : #define ITEM_IS_WITHIN_SVG_TEXT 0x8
    1485             :   /* The item allows items to be created for SVG <textPath> children. */
    1486             : #define ITEM_ALLOWS_TEXT_PATH_CHILD 0x10
    1487             :   /* The item is content created by an nsIAnonymousContentCreator frame */
    1488             : #define ITEM_IS_ANONYMOUSCONTENTCREATOR_CONTENT 0x20
    1489             :   // The guts of AddFrameConstructionItems
    1490             :   // aParentFrame might be null.  If it is, that means it was an
    1491             :   // inline frame.
    1492             :   void AddFrameConstructionItemsInternal(nsFrameConstructorState& aState,
    1493             :                                          nsIContent*              aContent,
    1494             :                                          nsContainerFrame*        aParentFrame,
    1495             :                                          nsIAtom*                 aTag,
    1496             :                                          int32_t                  aNameSpaceID,
    1497             :                                          bool                     aSuppressWhiteSpaceOptimizations,
    1498             :                                          nsStyleContext*          aStyleContext,
    1499             :                                          uint32_t                 aFlags,
    1500             :                                          nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren,
    1501             :                                          FrameConstructionItemList& aItems);
    1502             : 
    1503             :   /**
    1504             :    * Construct frames for the given item list and parent frame, and put the
    1505             :    * resulting frames in aFrameItems.
    1506             :    */
    1507             :   void ConstructFramesFromItemList(nsFrameConstructorState& aState,
    1508             :                                    FrameConstructionItemList& aItems,
    1509             :                                    nsContainerFrame* aParentFrame,
    1510             :                                    nsFrameItems& aFrameItems);
    1511             :   void ConstructFramesFromItem(nsFrameConstructorState& aState,
    1512             :                                FCItemIterator& aItem,
    1513             :                                nsContainerFrame* aParentFrame,
    1514             :                                nsFrameItems& aFrameItems);
    1515             :   static bool AtLineBoundary(FCItemIterator& aIter);
    1516             : 
    1517             :   nsresult GetAnonymousContent(nsIContent* aParent,
    1518             :                                nsIFrame* aParentFrame,
    1519             :                                nsTArray<nsIAnonymousContentCreator::ContentInfo>& aAnonContent);
    1520             : 
    1521             : //MathML Mod - RBS
    1522             :   /**
    1523             :    * Takes the frames in aBlockItems and wraps them in a new anonymous block
    1524             :    * frame whose content is aContent and whose parent will be aParentFrame.
    1525             :    * The anonymous block is added to aNewItems and aBlockItems is cleared.
    1526             :    */
    1527             :   void FlushAccumulatedBlock(nsFrameConstructorState& aState,
    1528             :                              nsIContent* aContent,
    1529             :                              nsContainerFrame* aParentFrame,
    1530             :                              nsFrameItems& aBlockItems,
    1531             :                              nsFrameItems& aNewItems);
    1532             : 
    1533             :   // Function to find FrameConstructionData for aContent.  Will return
    1534             :   // null if aContent is not MathML.
    1535             :   static const FrameConstructionData* FindMathMLData(Element* aElement,
    1536             :                                                      nsIAtom* aTag,
    1537             :                                                      int32_t aNameSpaceID,
    1538             :                                                      nsStyleContext* aStyleContext);
    1539             : 
    1540             :   // Function to find FrameConstructionData for aContent.  Will return
    1541             :   // null if aContent is not XUL.
    1542             :   static const FrameConstructionData* FindXULTagData(Element* aElement,
    1543             :                                                      nsIAtom* aTag,
    1544             :                                                      int32_t aNameSpaceID,
    1545             :                                                      nsStyleContext* aStyleContext);
    1546             :   // XUL data-finding helper functions and structures
    1547             : #ifdef MOZ_XUL
    1548             :   static const FrameConstructionData*
    1549             :     FindPopupGroupData(Element* aElement, nsStyleContext* aStyleContext);
    1550             :   // sXULTextBoxData used for both labels and descriptions
    1551             :   static const FrameConstructionData sXULTextBoxData;
    1552             :   static const FrameConstructionData*
    1553             :     FindXULLabelData(Element* aElement, nsStyleContext* aStyleContext);
    1554             :   static const FrameConstructionData*
    1555             :     FindXULDescriptionData(Element* aElement, nsStyleContext* aStyleContext);
    1556             : #ifdef XP_MACOSX
    1557             :   static const FrameConstructionData*
    1558             :     FindXULMenubarData(Element* aElement, nsStyleContext* aStyleContext);
    1559             : #endif /* XP_MACOSX */
    1560             :   static const FrameConstructionData*
    1561             :     FindXULListBoxBodyData(Element* aElement, nsStyleContext* aStyleContext);
    1562             :   static const FrameConstructionData*
    1563             :     FindXULListItemData(Element* aElement, nsStyleContext* aStyleContext);
    1564             : #endif /* MOZ_XUL */
    1565             : 
    1566             :   // Function to find FrameConstructionData for aContent using one of the XUL
    1567             :   // display types.  Will return null if aDisplay doesn't have a XUL display
    1568             :   // type.  This function performs no other checks, so should only be called if
    1569             :   // we know for sure that the content is not something that should get a frame
    1570             :   // constructed by tag.
    1571             :   static const FrameConstructionData*
    1572             :     FindXULDisplayData(const nsStyleDisplay* aDisplay,
    1573             :                        Element* aElement,
    1574             :                        nsStyleContext* aStyleContext);
    1575             : 
    1576             :   /**
    1577             :    * Constructs an outer frame, an anonymous child that wraps its real
    1578             :    * children, and its descendant frames.  This is used by both ConstructOuterSVG
    1579             :    * and ConstructMarker, which both want an anonymous block child for their
    1580             :    * children to go in to.
    1581             :    */
    1582             :   nsContainerFrame* ConstructFrameWithAnonymousChild(
    1583             :                                   nsFrameConstructorState& aState,
    1584             :                                   FrameConstructionItem&   aItem,
    1585             :                                   nsContainerFrame*        aParentFrame,
    1586             :                                   nsFrameItems&            aFrameItems,
    1587             :                                   ContainerFrameCreationFunc aConstructor,
    1588             :                                   ContainerFrameCreationFunc aInnerConstructor,
    1589             :                                   nsICSSAnonBoxPseudo*     aInnerPseudo,
    1590             :                                   bool                     aCandidateRootFrame);
    1591             : 
    1592             :   /**
    1593             :    * Construct an nsSVGOuterSVGFrame.
    1594             :    */
    1595             :   nsIFrame* ConstructOuterSVG(nsFrameConstructorState& aState,
    1596             :                               FrameConstructionItem&   aItem,
    1597             :                               nsContainerFrame*        aParentFrame,
    1598             :                               const nsStyleDisplay*    aDisplay,
    1599             :                               nsFrameItems&            aFrameItems);
    1600             : 
    1601             :   /**
    1602             :    * Construct an nsSVGMarkerFrame.
    1603             :    */
    1604             :   nsIFrame* ConstructMarker(nsFrameConstructorState& aState,
    1605             :                             FrameConstructionItem&   aItem,
    1606             :                             nsContainerFrame*        aParentFrame,
    1607             :                             const nsStyleDisplay*    aDisplay,
    1608             :                             nsFrameItems&            aFrameItems);
    1609             : 
    1610             :   static const FrameConstructionData* FindSVGData(Element* aElement,
    1611             :                                                   nsIAtom* aTag,
    1612             :                                                   int32_t aNameSpaceID,
    1613             :                                                   nsIFrame* aParentFrame,
    1614             :                                                   bool aIsWithinSVGText,
    1615             :                                                   bool aAllowsTextPathChild,
    1616             :                                                   nsStyleContext* aStyleContext);
    1617             : 
    1618             :   /* Not static because it does PropagateScrollToViewport.  If this
    1619             :      changes, make this static */
    1620             :   const FrameConstructionData*
    1621             :     FindDisplayData(const nsStyleDisplay* aDisplay, Element* aElement,
    1622             :                     nsStyleContext* aStyleContext);
    1623             : 
    1624             :   /**
    1625             :    * Construct a scrollable block frame
    1626             :    */
    1627             :   nsIFrame* ConstructScrollableBlock(nsFrameConstructorState& aState,
    1628             :                                      FrameConstructionItem&   aItem,
    1629             :                                      nsContainerFrame*        aParentFrame,
    1630             :                                      const nsStyleDisplay*    aDisplay,
    1631             :                                      nsFrameItems&            aFrameItems);
    1632             : 
    1633             :   /**
    1634             :    * Construct a scrollable block frame using the given block frame creation
    1635             :    * function.
    1636             :    */
    1637             :   nsIFrame* ConstructScrollableBlockWithConstructor(
    1638             :     nsFrameConstructorState& aState,
    1639             :     FrameConstructionItem& aItem,
    1640             :     nsContainerFrame* aParentFrame,
    1641             :     const nsStyleDisplay* aDisplay,
    1642             :     nsFrameItems& aFrameItems,
    1643             :     BlockFrameCreationFunc aConstructor);
    1644             : 
    1645             :   /**
    1646             :    * Construct a non-scrollable block frame
    1647             :    */
    1648             :   nsIFrame* ConstructNonScrollableBlock(nsFrameConstructorState& aState,
    1649             :                                         FrameConstructionItem&   aItem,
    1650             :                                         nsContainerFrame*        aParentFrame,
    1651             :                                         const nsStyleDisplay*    aDisplay,
    1652             :                                         nsFrameItems&            aFrameItems);
    1653             : 
    1654             :   /**
    1655             :    * Construct a non-scrollable block frame using the given block frame creation
    1656             :    * function.
    1657             :    */
    1658             :   nsIFrame* ConstructNonScrollableBlockWithConstructor(
    1659             :     nsFrameConstructorState& aState,
    1660             :     FrameConstructionItem& aItem,
    1661             :     nsContainerFrame* aParentFrame,
    1662             :     const nsStyleDisplay* aDisplay,
    1663             :     nsFrameItems& aFrameItems,
    1664             :     BlockFrameCreationFunc aConstructor);
    1665             : 
    1666             :   /**
    1667             :    * This adds FrameConstructionItem objects to aItemsToConstruct for the
    1668             :    * anonymous content returned by an nsIAnonymousContentCreator::
    1669             :    * CreateAnonymousContent implementation.
    1670             :    */
    1671             :   void AddFCItemsForAnonymousContent(
    1672             :             nsFrameConstructorState& aState,
    1673             :             nsContainerFrame* aFrame,
    1674             :             nsTArray<nsIAnonymousContentCreator::ContentInfo>& aAnonymousItems,
    1675             :             FrameConstructionItemList& aItemsToConstruct,
    1676             :             uint32_t aExtraFlags = 0);
    1677             : 
    1678             :   /**
    1679             :    * Construct the frames for the children of aContent.  "children" is defined
    1680             :    * as "whatever FlattenedChildIterator returns for aContent".  This means we're
    1681             :    * basically operating on children in the "flattened tree" per sXBL/XBL2.
    1682             :    * This method will also handle constructing ::before, ::after,
    1683             :    * ::first-letter, and ::first-line frames, as needed and if allowed.
    1684             :    *
    1685             :    * If the parent is a float containing block, this method will handle pushing
    1686             :    * it as the float containing block in aState (so there's no need for callers
    1687             :    * to push it themselves).
    1688             :    *
    1689             :    * @param aState the frame construction state
    1690             :    * @param aContent the content node whose children need frames
    1691             :    * @param aStyleContext the style context for aContent
    1692             :    * @param aParentFrame the frame to use as the parent frame for the new in-flow
    1693             :    *        kids. Note that this must be its own content insertion frame, but
    1694             :    *        need not be be the primary frame for aContent.  This frame will be
    1695             :    *        pushed as the float containing block, as needed.  aFrame is also
    1696             :    *        used to find the parent style context for the kids' style contexts
    1697             :    *        (not necessary aFrame's style context).
    1698             :    * @param aCanHaveGeneratedContent Whether to allow :before and
    1699             :    *        :after styles on the parent.
    1700             :    * @param aFrameItems the list in which we should place the in-flow children
    1701             :    * @param aAllowBlockStyles Whether to allow first-letter and first-line
    1702             :    *        styles on the parent.
    1703             :    * @param aPendingBinding Make sure to push this into aState before doing any
    1704             :    *        child item construction.
    1705             :    * @param aPossiblyLeafFrame if non-null, this should be used for the isLeaf
    1706             :    *        test and the anonymous content creation.  If null, aFrame will be
    1707             :    *        used.
    1708             :    */
    1709             :   void ProcessChildren(nsFrameConstructorState& aState,
    1710             :                        nsIContent*              aContent,
    1711             :                        nsStyleContext*          aStyleContext,
    1712             :                        nsContainerFrame*        aParentFrame,
    1713             :                        const bool               aCanHaveGeneratedContent,
    1714             :                        nsFrameItems&            aFrameItems,
    1715             :                        const bool               aAllowBlockStyles,
    1716             :                        PendingBinding*          aPendingBinding,
    1717             :                        nsIFrame*                aPossiblyLeafFrame = nullptr);
    1718             : 
    1719             :   /**
    1720             :    * These two functions are used when we start frame creation from a non-root
    1721             :    * element. They should recreate the same state that we would have
    1722             :    * arrived at if we had built frames from the root frame to aFrame.
    1723             :    * Therefore, any calls to PushFloatContainingBlock and
    1724             :    * PushAbsoluteContainingBlock during frame construction should get
    1725             :    * corresponding logic in these functions.
    1726             :    */
    1727             : public:
    1728             :   enum ContainingBlockType {
    1729             :     ABS_POS,
    1730             :     FIXED_POS
    1731             :   };
    1732             :   nsContainerFrame* GetAbsoluteContainingBlock(nsIFrame* aFrame,
    1733             :                                                ContainingBlockType aType);
    1734             :   nsContainerFrame* GetFloatContainingBlock(nsIFrame* aFrame);
    1735             : 
    1736             : private:
    1737             :   // Build a scroll frame:
    1738             :   //  Calls BeginBuildingScrollFrame, InitAndRestoreFrame, and then FinishBuildingScrollFrame.
    1739             :   // @param aNewFrame the created scrollframe --- output only
    1740             :   // @param aParentFrame the geometric parent that the scrollframe will have.
    1741             :   void
    1742             :   BuildScrollFrame(nsFrameConstructorState& aState,
    1743             :                    nsIContent*              aContent,
    1744             :                    nsStyleContext*          aContentStyle,
    1745             :                    nsIFrame*                aScrolledFrame,
    1746             :                    nsContainerFrame*        aParentFrame,
    1747             :                    nsContainerFrame*&       aNewFrame);
    1748             : 
    1749             :   // Builds the initial ScrollFrame
    1750             :   already_AddRefed<nsStyleContext>
    1751             :   BeginBuildingScrollFrame(nsFrameConstructorState& aState,
    1752             :                            nsIContent*              aContent,
    1753             :                            nsStyleContext*          aContentStyle,
    1754             :                            nsContainerFrame*        aParentFrame,
    1755             :                            nsIAtom*                 aScrolledPseudo,
    1756             :                            bool                     aIsRoot,
    1757             :                            nsContainerFrame*&       aNewFrame);
    1758             : 
    1759             :   // Completes the building of the scrollframe:
    1760             :   // Creates a view for the scrolledframe and makes it the child of the scrollframe.
    1761             :   void
    1762             :   FinishBuildingScrollFrame(nsContainerFrame* aScrollFrame,
    1763             :                             nsIFrame* aScrolledFrame);
    1764             : 
    1765             :   // InitializeSelectFrame puts scrollFrame in aFrameItems if aBuildCombobox is false
    1766             :   // aBuildCombobox indicates if we are building a combobox that has a dropdown
    1767             :   // popup widget or not.
    1768             :   void
    1769             :   InitializeSelectFrame(nsFrameConstructorState& aState,
    1770             :                         nsContainerFrame*        aScrollFrame,
    1771             :                         nsContainerFrame*        aScrolledFrame,
    1772             :                         nsIContent*              aContent,
    1773             :                         nsContainerFrame*        aParentFrame,
    1774             :                         nsStyleContext*          aStyleContext,
    1775             :                         bool                     aBuildCombobox,
    1776             :                         PendingBinding*          aPendingBinding,
    1777             :                         nsFrameItems&            aFrameItems);
    1778             : 
    1779             :   /**
    1780             :    * ReResolve style for aElement then recreate frames if required.
    1781             :    * Do nothing for other types of style changes, except for undisplayed nodes
    1782             :    * (display:none/contents) which will have their style context updated in the
    1783             :    * frame manager undisplayed maps.
    1784             :    * @return null if frames were recreated, the new style context otherwise
    1785             :    */
    1786             :   nsStyleContext* MaybeRecreateFramesForElement(Element* aElement);
    1787             : 
    1788             :   /**
    1789             :    * Recreate frames for aContent.
    1790             :    * @param aContent the content to recreate frames for
    1791             :    * @param aAsyncInsert if true then a restyle event will be posted to handle
    1792             :    *   the required ContentInserted call instead of doing it immediately.
    1793             :    * @param aFlags normally you want to pass REMOVE_FOR_RECONSTRUCTION here
    1794             :    * @param aDestroyedFramesFor if non-null, it will contain the content that
    1795             :    *   was actually reframed - it may be different than aContent.
    1796             :    */
    1797             :   void
    1798             :   RecreateFramesForContent(nsIContent*  aContent,
    1799             :                            bool         aAsyncInsert,
    1800             :                            RemoveFlags  aFlags,
    1801             :                            nsIContent** aDestroyedFramesFor);
    1802             : 
    1803             :   // If removal of aFrame from the frame tree requires reconstruction of some
    1804             :   // containing block (either of aFrame or of its parent) due to {ib} splits or
    1805             :   // table pseudo-frames, recreate the relevant frame subtree.  The return value
    1806             :   // indicates whether this happened.  If this method returns true, *aResult is
    1807             :   // the return value of ReframeContainingBlock or RecreateFramesForContent.  If
    1808             :   // this method returns false, the value of *aResult is not affected.  aFrame
    1809             :   // and aResult must not be null.  aFrame must be the result of a
    1810             :   // GetPrimaryFrame() call on a content node (which means its parent is also
    1811             :   // not null).   If this method returns true, aDestroyedFramesFor contains the
    1812             :   // content that was reframed.
    1813             :   bool MaybeRecreateContainerForFrameRemoval(nsIFrame*    aFrame,
    1814             :                                              RemoveFlags  aFlags,
    1815             :                                              nsIContent** aDestroyedFramesFor);
    1816             : 
    1817             :   nsIFrame* CreateContinuingOuterTableFrame(nsIPresShell*     aPresShell,
    1818             :                                             nsPresContext*    aPresContext,
    1819             :                                             nsIFrame*         aFrame,
    1820             :                                             nsContainerFrame* aParentFrame,
    1821             :                                             nsIContent*       aContent,
    1822             :                                             nsStyleContext*   aStyleContext);
    1823             : 
    1824             :   nsIFrame* CreateContinuingTableFrame(nsIPresShell*     aPresShell,
    1825             :                                        nsIFrame*         aFrame,
    1826             :                                        nsContainerFrame* aParentFrame,
    1827             :                                        nsIContent*       aContent,
    1828             :                                        nsStyleContext*   aStyleContext);
    1829             : 
    1830             :   //----------------------------------------
    1831             : 
    1832             :   // Methods support creating block frames and their children
    1833             : 
    1834             :   already_AddRefed<nsStyleContext>
    1835             :   GetFirstLetterStyle(nsIContent*      aContent,
    1836             :                       nsStyleContext*  aStyleContext);
    1837             : 
    1838             :   already_AddRefed<nsStyleContext>
    1839             :   GetFirstLineStyle(nsIContent*      aContent,
    1840             :                     nsStyleContext*  aStyleContext);
    1841             : 
    1842             :   bool ShouldHaveFirstLetterStyle(nsIContent*      aContent,
    1843             :                                     nsStyleContext*  aStyleContext);
    1844             : 
    1845             :   // Check whether a given block has first-letter style.  Make sure to
    1846             :   // only pass in blocks!  And don't pass in null either.
    1847             :   bool HasFirstLetterStyle(nsIFrame* aBlockFrame);
    1848             : 
    1849             :   bool ShouldHaveFirstLineStyle(nsIContent*      aContent,
    1850             :                                   nsStyleContext*  aStyleContext);
    1851             : 
    1852             :   void ShouldHaveSpecialBlockStyle(nsIContent*      aContent,
    1853             :                                    nsStyleContext*  aStyleContext,
    1854             :                                    bool*          aHaveFirstLetterStyle,
    1855             :                                    bool*          aHaveFirstLineStyle);
    1856             : 
    1857             :   // |aContentParentFrame| should be null if it's really the same as
    1858             :   // |aParentFrame|.
    1859             :   // @param aFrameItems where we want to put the block in case it's in-flow.
    1860             :   // @param aNewFrame an in/out parameter. On input it is the block to be
    1861             :   // constructed. On output it is reset to the outermost
    1862             :   // frame constructed (e.g. if we need to wrap the block in an
    1863             :   // nsColumnSetFrame.
    1864             :   // @param aParentFrame is the desired parent for the (possibly wrapped)
    1865             :   // block
    1866             :   // @param aContentParent is the parent the block would have if it
    1867             :   // were in-flow
    1868             :   // @param aPositionedFrameForAbsPosContainer if non-null, then the new
    1869             :   // block should be an abs-pos container and aPositionedFrameForAbsPosContainer
    1870             :   // is the frame whose style is making this block an abs-pos container.
    1871             :   // @param aPendingBinding the pending binding  from this block's frame
    1872             :   // construction item.
    1873             :   void ConstructBlock(nsFrameConstructorState& aState,
    1874             :                       nsIContent*              aContent,
    1875             :                       nsContainerFrame*        aParentFrame,
    1876             :                       nsContainerFrame*        aContentParentFrame,
    1877             :                       nsStyleContext*          aStyleContext,
    1878             :                       nsContainerFrame**       aNewFrame,
    1879             :                       nsFrameItems&            aFrameItems,
    1880             :                       nsIFrame*                aPositionedFrameForAbsPosContainer,
    1881             :                       PendingBinding*          aPendingBinding);
    1882             : 
    1883             :   nsIFrame* ConstructInline(nsFrameConstructorState& aState,
    1884             :                             FrameConstructionItem&   aItem,
    1885             :                             nsContainerFrame*        aParentFrame,
    1886             :                             const nsStyleDisplay*    aDisplay,
    1887             :                             nsFrameItems&            aFrameItems);
    1888             : 
    1889             :   /**
    1890             :    * Create any additional {ib} siblings needed to contain aChildItems and put
    1891             :    * them in aSiblings.
    1892             :    *
    1893             :    * @param aState the frame constructor state
    1894             :    * @param aInitialInline is an already-existing inline frame that will be
    1895             :    *                       part of this {ib} split and come before everything
    1896             :    *                       in aSiblings.
    1897             :    * @param aIsPositioned true if aInitialInline is positioned.
    1898             :    * @param aChildItems is a child list starting with a block; this method
    1899             :    *                    assumes that the inline has already taken all the
    1900             :    *                    children it wants.  When the method returns aChildItems
    1901             :    *                    will be empty.
    1902             :    * @param aSiblings the nsFrameItems to put the newly-created siblings into.
    1903             :    *
    1904             :    * This method is responsible for making any SetFrameIsIBSplit calls that are
    1905             :    * needed.
    1906             :    */
    1907             :   void CreateIBSiblings(nsFrameConstructorState& aState,
    1908             :                         nsContainerFrame* aInitialInline,
    1909             :                         bool aIsPositioned,
    1910             :                         nsFrameItems& aChildItems,
    1911             :                         nsFrameItems& aSiblings);
    1912             : 
    1913             :   /**
    1914             :    * For an inline aParentItem, construct its list of child
    1915             :    * FrameConstructionItems and set its mIsAllInline flag appropriately.
    1916             :    */
    1917             :   void BuildInlineChildItems(nsFrameConstructorState& aState,
    1918             :                              FrameConstructionItem& aParentItem,
    1919             :                              bool aItemIsWithinSVGText,
    1920             :                              bool aItemAllowsTextPathChild);
    1921             : 
    1922             :   // Determine whether we need to wipe out what we just did and start over
    1923             :   // because we're doing something like adding block kids to an inline frame
    1924             :   // (and therefore need an {ib} split).  aPrevSibling must be correct, even in
    1925             :   // aIsAppend cases.  Passing aIsAppend false even when an append is happening
    1926             :   // is ok in terms of correctness, but can lead to unnecessary reframing.  If
    1927             :   // aIsAppend is true, then the caller MUST call
    1928             :   // nsCSSFrameConstructor::AppendFramesToParent (as opposed to
    1929             :   // nsFrameManager::InsertFrames directly) to add the new frames.
    1930             :   // @return true if we reconstructed the containing block, false
    1931             :   // otherwise
    1932             :   bool WipeContainingBlock(nsFrameConstructorState& aState,
    1933             :                              nsIFrame*                aContainingBlock,
    1934             :                              nsIFrame*                aFrame,
    1935             :                              FrameConstructionItemList& aItems,
    1936             :                              bool                     aIsAppend,
    1937             :                              nsIFrame*                aPrevSibling);
    1938             : 
    1939             :   void ReframeContainingBlock(nsIFrame*    aFrame,
    1940             :                               RemoveFlags  aFlags,
    1941             :                               nsIContent** aReframeContent);
    1942             : 
    1943             :   //----------------------------------------
    1944             : 
    1945             :   // Methods support :first-letter style
    1946             : 
    1947             :   nsFirstLetterFrame*
    1948             :   CreateFloatingLetterFrame(nsFrameConstructorState& aState,
    1949             :                             nsIContent*              aTextContent,
    1950             :                             nsIFrame*                aTextFrame,
    1951             :                             nsContainerFrame*        aParentFrame,
    1952             :                             nsStyleContext*          aStyleContext,
    1953             :                             nsFrameItems&            aResult);
    1954             : 
    1955             :   void CreateLetterFrame(nsContainerFrame*        aBlockFrame,
    1956             :                          nsContainerFrame*        aBlockContinuation,
    1957             :                          nsIContent*              aTextContent,
    1958             :                          nsContainerFrame*        aParentFrame,
    1959             :                          nsFrameItems&            aResult);
    1960             : 
    1961             :   void WrapFramesInFirstLetterFrame(nsContainerFrame* aBlockFrame,
    1962             :                                     nsFrameItems&     aBlockFrames);
    1963             : 
    1964             :   /**
    1965             :    * Looks in the block aBlockFrame for a text frame that contains the
    1966             :    * first-letter of the block and creates the necessary first-letter frames
    1967             :    * and returns them in aLetterFrames.
    1968             :    *
    1969             :    * @param aBlockFrame the (first-continuation of) the block we are creating a
    1970             :    *                    first-letter frame for
    1971             :    * @param aBlockContinuation the current continuation of the block that we
    1972             :    *                           are looking in for a textframe with suitable
    1973             :    *                           contents for first-letter
    1974             :    * @param aParentFrame the current frame whose children we are looking at for
    1975             :    *                     a suitable first-letter textframe
    1976             :    * @param aParentFrameList the first child of aParentFrame
    1977             :    * @param aModifiedParent returns the parent of the textframe that contains
    1978             :    *                        the first-letter
    1979             :    * @param aTextFrame returns the textframe that had the first-letter
    1980             :    * @param aPrevFrame returns the previous sibling of aTextFrame
    1981             :    * @param aLetterFrames returns the frames that were created
    1982             :    */
    1983             :   void WrapFramesInFirstLetterFrame(nsContainerFrame*  aBlockFrame,
    1984             :                                     nsContainerFrame*  aBlockContinuation,
    1985             :                                     nsContainerFrame*  aParentFrame,
    1986             :                                     nsIFrame*          aParentFrameList,
    1987             :                                     nsContainerFrame** aModifiedParent,
    1988             :                                     nsIFrame**         aTextFrame,
    1989             :                                     nsIFrame**         aPrevFrame,
    1990             :                                     nsFrameItems&      aLetterFrames,
    1991             :                                     bool*              aStopLooking);
    1992             : 
    1993             :   void RecoverLetterFrames(nsContainerFrame* aBlockFrame);
    1994             : 
    1995             :   //
    1996             :   void RemoveLetterFrames(nsIPresShell*     aPresShell,
    1997             :                           nsContainerFrame* aBlockFrame);
    1998             : 
    1999             :   // Recursive helper for RemoveLetterFrames
    2000             :   void RemoveFirstLetterFrames(nsIPresShell*     aPresShell,
    2001             :                                nsContainerFrame* aFrame,
    2002             :                                nsContainerFrame* aBlockFrame,
    2003             :                                bool*             aStopLooking);
    2004             : 
    2005             :   // Special remove method for those pesky floating first-letter frames
    2006             :   void RemoveFloatingFirstLetterFrames(nsIPresShell*    aPresShell,
    2007             :                                        nsIFrame*        aBlockFrame);
    2008             : 
    2009             :   // Capture state for the frame tree rooted at the frame associated with the
    2010             :   // content object, aContent
    2011             :   void CaptureStateForFramesOf(nsIContent* aContent,
    2012             :                                nsILayoutHistoryState* aHistoryState);
    2013             : 
    2014             :   //----------------------------------------
    2015             : 
    2016             :   // Methods support :first-line style
    2017             : 
    2018             :   // This method chops the initial inline-outside frames out of aFrameItems.
    2019             :   // If aLineFrame is non-null, it appends them to that frame.  Otherwise, it
    2020             :   // creates a new line frame, sets the inline frames as its initial child
    2021             :   // list, and inserts that line frame at the front of what's left of
    2022             :   // aFrameItems.  In both cases, the kids are reparented to the line frame.
    2023             :   // After this call, aFrameItems holds the frames that need to become kids of
    2024             :   // the block (possibly including line frames).
    2025             :   void WrapFramesInFirstLineFrame(nsFrameConstructorState& aState,
    2026             :                                   nsIContent*              aBlockContent,
    2027             :                                   nsContainerFrame*        aBlockFrame,
    2028             :                                   nsFirstLineFrame*        aLineFrame,
    2029             :                                   nsFrameItems&            aFrameItems);
    2030             : 
    2031             :   // Handle the case when a block with first-line style is appended to (by
    2032             :   // possibly calling WrapFramesInFirstLineFrame as needed).
    2033             :   void AppendFirstLineFrames(nsFrameConstructorState& aState,
    2034             :                              nsIContent*              aContent,
    2035             :                              nsContainerFrame*        aBlockFrame,
    2036             :                              nsFrameItems&            aFrameItems);
    2037             : 
    2038             :   void InsertFirstLineFrames(nsFrameConstructorState& aState,
    2039             :                              nsIContent*              aContent,
    2040             :                              nsIFrame*                aBlockFrame,
    2041             :                              nsContainerFrame**       aParentFrame,
    2042             :                              nsIFrame*                aPrevSibling,
    2043             :                              nsFrameItems&            aFrameItems);
    2044             : 
    2045             :   /**
    2046             :    * Find the right frame to use for aContent when looking for sibling
    2047             :    * frames for aTargetContent.  If aPrevSibling is true, this
    2048             :    * will look for last continuations, etc, as necessary.  This calls
    2049             :    * IsValidSibling as needed; if that returns false it returns null.
    2050             :    *
    2051             :    * @param aContent the content to search for frames
    2052             :    * @param aTargetContent the content we're finding a sibling frame for
    2053             :    * @param aTargetContentDisplay the CSS display enum for aTargetContent if
    2054             :    *          already known, UNSET_DISPLAY otherwise. It will be filled in
    2055             :    *          if needed.
    2056             :    * @param aParentFrame the nearest ancestor frame, used internally for
    2057             :    *          finding ::after / ::before frames
    2058             :    * @param aPrevSibling true if we're searching in reverse DOM order
    2059             :    */
    2060             :   nsIFrame* FindFrameForContentSibling(nsIContent* aContent,
    2061             :                                        nsIContent* aTargetContent,
    2062             :                                        mozilla::StyleDisplay& aTargetContentDisplay,
    2063             :                                        nsContainerFrame* aParentFrame,
    2064             :                                        bool aPrevSibling);
    2065             : 
    2066             :   /**
    2067             :    * Find the frame for the content immediately preceding the one aIter
    2068             :    * points to, following continuations if necessary.  aIter is passed by
    2069             :    * value on purpose, so as not to modify the caller's iterator.
    2070             :    *
    2071             :    * @param aIter should be positioned such that aIter.GetPreviousChild()
    2072             :    *          is the first content to search for frames
    2073             :    * @param aTargetContent the content we're finding a sibling frame for
    2074             :    * @param aTargetContentDisplay the CSS display enum for aTargetContent if
    2075             :    *          already known, UNSET_DISPLAY otherwise. It will be filled in
    2076             :    *          if needed.
    2077             :    * @param aParentFrame the nearest ancestor frame, used inernally for
    2078             :    *          finding ::after / ::before frames
    2079             :    */
    2080             :   nsIFrame* FindPreviousSibling(mozilla::dom::FlattenedChildIterator aIter,
    2081             :                                 nsIContent* aTargetContent,
    2082             :                                 mozilla::StyleDisplay& aTargetContentDisplay,
    2083             :                                 nsContainerFrame* aParentFrame);
    2084             : 
    2085             :   /**
    2086             :    * Find the frame for the content node immediately following the one aIter
    2087             :    * points to, following continuations if necessary.  aIter is passed by value
    2088             :    * on purpose, so as not to modify the caller's iterator.
    2089             :    *
    2090             :    * @param aIter should be positioned such that aIter.GetNextChild()
    2091             :    *          is the first content to search for frames
    2092             :    * @param aTargetContent the content we're finding a sibling frame for
    2093             :    * @param aTargetContentDisplay the CSS display enum for aTargetContent if
    2094             :    *          already known, UNSET_DISPLAY otherwise. It will be filled in
    2095             :    *          if needed.
    2096             :    * @param aParentFrame the nearest ancestor frame, used inernally for
    2097             :    *          finding ::after / ::before frames
    2098             :    */
    2099             :   nsIFrame* FindNextSibling(mozilla::dom::FlattenedChildIterator aIter,
    2100             :                             nsIContent* aTargetContent,
    2101             :                             mozilla::StyleDisplay& aTargetContentDisplay,
    2102             :                             nsContainerFrame* aParentFrame);
    2103             : 
    2104             :   // Find the right previous sibling for an insertion.  This also updates the
    2105             :   // parent frame to point to the correct continuation of the parent frame to
    2106             :   // use, and returns whether this insertion is to be treated as an append.
    2107             :   // aChild is the child being inserted.
    2108             :   // aIsRangeInsertSafe returns whether it is safe to do a range insert with
    2109             :   // aChild being the first child in the range. It is the callers'
    2110             :   // responsibility to check whether a range insert is safe with regards to
    2111             :   // fieldsets.
    2112             :   // The skip parameters are used to ignore a range of children when looking
    2113             :   // for a sibling. All nodes starting from aStartSkipChild and up to but not
    2114             :   // including aEndSkipChild will be skipped over when looking for sibling
    2115             :   // frames. Skipping a range can deal with XBL but not when there are multiple
    2116             :   // insertion points.
    2117             :   nsIFrame* GetInsertionPrevSibling(InsertionPoint* aInsertion, // inout
    2118             :                                     nsIContent* aChild,
    2119             :                                     bool* aIsAppend,
    2120             :                                     bool* aIsRangeInsertSafe,
    2121             :                                     nsIContent* aStartSkipChild = nullptr,
    2122             :                                     nsIContent *aEndSkipChild = nullptr);
    2123             : 
    2124             :   /**
    2125             :    * Return the insertion frame of the primary frame of aContent, or its nearest
    2126             :    * ancestor that isn't display:contents.
    2127             :    */
    2128             :   nsContainerFrame* GetContentInsertionFrameFor(nsIContent* aContent);
    2129             : 
    2130             :   // see if aContent and aSibling are legitimate siblings due to restrictions
    2131             :   // imposed by table columns
    2132             :   // XXXbz this code is generally wrong, since the frame for aContent
    2133             :   // may be constructed based on tag, not based on aDisplay!
    2134             :   bool IsValidSibling(nsIFrame*              aSibling,
    2135             :                       nsIContent*            aContent,
    2136             :                       mozilla::StyleDisplay& aDisplay);
    2137             : 
    2138             :   void QuotesDirty();
    2139             :   void CountersDirty();
    2140             : 
    2141             :   /**
    2142             :    * Add the pair (aContent, aStyleContext) to the undisplayed items
    2143             :    * in aList as needed.  This method enforces the invariant that all
    2144             :    * style contexts in the undisplayed content map must be non-pseudo
    2145             :    * contexts and also handles unbinding undisplayed generated content
    2146             :    * as needed.
    2147             :    */
    2148             :   void SetAsUndisplayedContent(nsFrameConstructorState& aState,
    2149             :                                FrameConstructionItemList& aList,
    2150             :                                nsIContent* aContent,
    2151             :                                nsStyleContext* aStyleContext,
    2152             :                                bool aIsGeneratedContent);
    2153             :   // Create touch caret frame.
    2154             :   void ConstructAnonymousContentForCanvas(nsFrameConstructorState& aState,
    2155             :                                           nsIFrame* aFrame,
    2156             :                                           nsIContent* aDocElement);
    2157             : 
    2158             : public:
    2159             : 
    2160             :   friend class nsFrameConstructorState;
    2161             : 
    2162             : private:
    2163             : 
    2164             :   nsIDocument*        mDocument;  // Weak ref
    2165             : 
    2166             :   // See the comment at the start of ConstructRootFrame for more details
    2167             :   // about the following frames.
    2168             : 
    2169             :   // This is just the outermost frame for the root element.
    2170             :   nsContainerFrame*   mRootElementFrame;
    2171             :   // This is the frame for the root element that has no pseudo-element style.
    2172             :   nsIFrame*           mRootElementStyleFrame;
    2173             :   // This is the containing block that contains the root element ---
    2174             :   // the real "initial containing block" according to CSS 2.1.
    2175             :   nsContainerFrame*   mDocElementContainingBlock;
    2176             :   nsIFrame*           mPageSequenceFrame;
    2177             :   nsQuoteList         mQuoteList;
    2178             :   nsCounterManager    mCounterManager;
    2179             :   // Current ProcessChildren depth.
    2180             :   uint16_t            mCurrentDepth;
    2181             : #ifdef DEBUG
    2182             :   uint16_t            mUpdateCount;
    2183             : #endif
    2184             :   bool                mQuotesDirty : 1;
    2185             :   bool                mCountersDirty : 1;
    2186             :   bool                mIsDestroyingFrameTree : 1;
    2187             :   // This is true if mDocElementContainingBlock supports absolute positioning
    2188             :   bool                mHasRootAbsPosContainingBlock : 1;
    2189             :   bool                mAlwaysCreateFramesForIgnorableWhitespace : 1;
    2190             : 
    2191             :   nsCOMPtr<nsILayoutHistoryState> mTempFrameTreeState;
    2192             : };
    2193             : 
    2194             : #endif /* nsCSSFrameConstructor_h___ */

Generated by: LCOV version 1.13