layout/base/nsCSSFrameConstructor.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/base/nsCSSFrameConstructor.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1809 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +/*
    1.10 + * construction of a frame tree that is nearly isomorphic to the content
    1.11 + * tree and updating of that tree in response to dynamic changes
    1.12 + */
    1.13 +
    1.14 +#ifndef nsCSSFrameConstructor_h___
    1.15 +#define nsCSSFrameConstructor_h___
    1.16 +
    1.17 +#include "mozilla/Attributes.h"
    1.18 +
    1.19 +#include "nsCOMPtr.h"
    1.20 +#include "nsILayoutHistoryState.h"
    1.21 +#include "nsQuoteList.h"
    1.22 +#include "nsCounterManager.h"
    1.23 +#include "nsCSSPseudoElements.h"
    1.24 +#include "nsIAnonymousContentCreator.h"
    1.25 +#include "nsFrameManager.h"
    1.26 +#include "nsIDocument.h"
    1.27 +
    1.28 +struct nsFrameItems;
    1.29 +struct nsAbsoluteItems;
    1.30 +class nsStyleContext;
    1.31 +struct nsStyleDisplay;
    1.32 +class nsIDOMHTMLSelectElement;
    1.33 +struct nsGenConInitializer;
    1.34 +
    1.35 +class nsICSSAnonBoxPseudo;
    1.36 +class nsPageContentFrame;
    1.37 +struct PendingBinding;
    1.38 +class nsGenericDOMDataNode;
    1.39 +
    1.40 +class nsFrameConstructorState;
    1.41 +class nsFrameConstructorSaveState;
    1.42 +
    1.43 +namespace mozilla {
    1.44 +
    1.45 +class RestyleManager;
    1.46 +
    1.47 +namespace dom {
    1.48 +
    1.49 +class FlattenedChildIterator;
    1.50 +
    1.51 +}
    1.52 +}
    1.53 +
    1.54 +class nsCSSFrameConstructor : public nsFrameManager
    1.55 +{
    1.56 +public:
    1.57 +  typedef mozilla::dom::Element Element;
    1.58 +
    1.59 +  friend class mozilla::RestyleManager;
    1.60 +
    1.61 +  nsCSSFrameConstructor(nsIDocument *aDocument, nsIPresShell* aPresShell,
    1.62 +                        nsStyleSet* aStyleSet);
    1.63 +  ~nsCSSFrameConstructor(void) {
    1.64 +    NS_ASSERTION(mUpdateCount == 0, "Dying in the middle of our own update?");
    1.65 +  }
    1.66 +
    1.67 +  // get the alternate text for a content node
    1.68 +  static void GetAlternateTextFor(nsIContent*    aContent,
    1.69 +                                  nsIAtom*       aTag,  // content object's tag
    1.70 +                                  nsXPIDLString& aAltText);
    1.71 +
    1.72 +private:
    1.73 +  nsCSSFrameConstructor(const nsCSSFrameConstructor& aCopy) MOZ_DELETE;
    1.74 +  nsCSSFrameConstructor& operator=(const nsCSSFrameConstructor& aCopy) MOZ_DELETE;
    1.75 +
    1.76 +public:
    1.77 +  mozilla::RestyleManager* RestyleManager() const
    1.78 +    { return mPresShell->GetPresContext()->RestyleManager(); }
    1.79 +
    1.80 +  nsIFrame* ConstructRootFrame();
    1.81 +
    1.82 +  nsresult ReconstructDocElementHierarchy();
    1.83 +
    1.84 +  // Create frames for content nodes that are marked as needing frames. This
    1.85 +  // should be called before ProcessPendingRestyles.
    1.86 +  // Note: It's the caller's responsibility to make sure to wrap a
    1.87 +  // CreateNeededFrames call in a view update batch and a script blocker.
    1.88 +  void CreateNeededFrames();
    1.89 +
    1.90 +private:
    1.91 +  void CreateNeededFrames(nsIContent* aContent);
    1.92 +
    1.93 +  enum Operation {
    1.94 +    CONTENTAPPEND,
    1.95 +    CONTENTINSERT
    1.96 +  };
    1.97 +
    1.98 +  // aChild is the child being inserted for inserts, and the first
    1.99 +  // child being appended for appends.
   1.100 +  bool MaybeConstructLazily(Operation aOperation,
   1.101 +                              nsIContent* aContainer,
   1.102 +                              nsIContent* aChild);
   1.103 +
   1.104 +  // Issues a single ContentInserted for each child of aContainer in the range
   1.105 +  // [aStartChild, aEndChild).
   1.106 +  void IssueSingleInsertNofications(nsIContent* aContainer,
   1.107 +                                    nsIContent* aStartChild,
   1.108 +                                    nsIContent* aEndChild,
   1.109 +                                    bool aAllowLazyConstruction);
   1.110 +
   1.111 +  // Checks if the children of aContainer in the range [aStartChild, aEndChild)
   1.112 +  // can be inserted/appended to one insertion point together. If so, returns
   1.113 +  // that insertion point. If not, returns null and issues single
   1.114 +  // ContentInserted calls for each child.  aEndChild = nullptr indicates that we
   1.115 +  // are dealing with an append.
   1.116 +  nsIFrame* GetRangeInsertionPoint(nsIContent* aContainer,
   1.117 +                                   nsIContent* aStartChild,
   1.118 +                                   nsIContent* aEndChild,
   1.119 +                                   bool aAllowLazyConstruction);
   1.120 +
   1.121 +  // Returns true if parent was recreated due to frameset child, false otherwise.
   1.122 +  bool MaybeRecreateForFrameset(nsIFrame* aParentFrame,
   1.123 +                                  nsIContent* aStartChild,
   1.124 +                                  nsIContent* aEndChild);
   1.125 +
   1.126 +public:
   1.127 +  /**
   1.128 +   * Lazy frame construction is controlled by the aAllowLazyConstruction bool
   1.129 +   * parameter of nsCSSFrameConstructor::ContentAppended/Inserted. It is true
   1.130 +   * for all inserts/appends as passed from the presshell, except for the
   1.131 +   * insert of the root element, which is always non-lazy. Even if the
   1.132 +   * aAllowLazyConstruction passed to ContentAppended/Inserted is true we still
   1.133 +   * may not be able to construct lazily, so we call MaybeConstructLazily.
   1.134 +   * MaybeConstructLazily does not allow lazy construction if any of the
   1.135 +   * following are true:
   1.136 +   *  -we are in chrome
   1.137 +   *  -the container is in a native anonymous subtree
   1.138 +   *  -the container is XUL
   1.139 +   *  -is any of the appended/inserted nodes are XUL or editable
   1.140 +   *  -(for inserts) the child is anonymous.  In the append case this function
   1.141 +   *   must not be called with anonymous children.
   1.142 +   * The XUL and chrome checks are because XBL bindings only get applied at
   1.143 +   * frame construction time and some things depend on the bindings getting
   1.144 +   * attached synchronously. The editable checks are because the editor seems
   1.145 +   * to expect frames to be constructed synchronously.
   1.146 +   *
   1.147 +   * If MaybeConstructLazily returns false we construct as usual, but if it
   1.148 +   * returns true then it adds NODE_NEEDS_FRAME bits to the newly
   1.149 +   * inserted/appended nodes and adds NODE_DESCENDANTS_NEED_FRAMES bits to the
   1.150 +   * container and up along the parent chain until it hits the root or another
   1.151 +   * node with that bit set. Then it posts a restyle event to ensure that a
   1.152 +   * flush happens to construct those frames.
   1.153 +   *
   1.154 +   * When the flush happens the presshell calls
   1.155 +   * nsCSSFrameConstructor::CreateNeededFrames. CreateNeededFrames follows any
   1.156 +   * nodes with NODE_DESCENDANTS_NEED_FRAMES set down the content tree looking
   1.157 +   * for nodes with NODE_NEEDS_FRAME set. It calls ContentAppended for any runs
   1.158 +   * of nodes with NODE_NEEDS_FRAME set that are at the end of their childlist,
   1.159 +   * and ContentRangeInserted for any other runs that aren't.
   1.160 +   *
   1.161 +   * If a node is removed from the document then we don't bother unsetting any
   1.162 +   * of the lazy bits that might be set on it, its descendants, or any of its
   1.163 +   * ancestor nodes because that is a slow operation, the work might be wasted
   1.164 +   * if another node gets inserted in its place, and we can clear the bits
   1.165 +   * quicker by processing the content tree from top down the next time we call
   1.166 +   * CreateNeededFrames. (We do clear the bits when BindToTree is called on any
   1.167 +   * nsIContent; so any nodes added to the document will not have any lazy bits
   1.168 +   * set.)
   1.169 +   */
   1.170 +
   1.171 +  // If aAllowLazyConstruction is true then frame construction of the new
   1.172 +  // children can be done lazily.
   1.173 +  nsresult ContentAppended(nsIContent* aContainer,
   1.174 +                           nsIContent* aFirstNewContent,
   1.175 +                           bool        aAllowLazyConstruction);
   1.176 +
   1.177 +  // If aAllowLazyConstruction is true then frame construction of the new child
   1.178 +  // can be done lazily.
   1.179 +  nsresult ContentInserted(nsIContent*            aContainer,
   1.180 +                           nsIContent*            aChild,
   1.181 +                           nsILayoutHistoryState* aFrameState,
   1.182 +                           bool                   aAllowLazyConstruction);
   1.183 +
   1.184 +  // Like ContentInserted but handles inserting the children of aContainer in
   1.185 +  // the range [aStartChild, aEndChild).  aStartChild must be non-null.
   1.186 +  // aEndChild may be null to indicate the range includes all kids after
   1.187 +  // aStartChild.  If aAllowLazyConstruction is true then frame construction of
   1.188 +  // the new children can be done lazily. It is only allowed to be true when
   1.189 +  // inserting a single node.
   1.190 +  nsresult ContentRangeInserted(nsIContent*            aContainer,
   1.191 +                                nsIContent*            aStartChild,
   1.192 +                                nsIContent*            aEndChild,
   1.193 +                                nsILayoutHistoryState* aFrameState,
   1.194 +                                bool                   aAllowLazyConstruction);
   1.195 +
   1.196 +  enum RemoveFlags { REMOVE_CONTENT, REMOVE_FOR_RECONSTRUCTION };
   1.197 +  nsresult ContentRemoved(nsIContent* aContainer,
   1.198 +                          nsIContent* aChild,
   1.199 +                          nsIContent* aOldNextSibling,
   1.200 +                          RemoveFlags aFlags,
   1.201 +                          bool*     aDidReconstruct);
   1.202 +
   1.203 +  nsresult CharacterDataChanged(nsIContent* aContent,
   1.204 +                                CharacterDataChangeInfo* aInfo);
   1.205 +
   1.206 +  // If aContent is a text node that has been optimized away due to being
   1.207 +  // whitespace next to a block boundary (or for some other reason), stop
   1.208 +  // doing that and create a frame for it if it should have one. This recreates
   1.209 +  // frames so be careful (although this should not change actual layout).
   1.210 +  // Returns the frame for aContent if there is one.
   1.211 +  nsIFrame* EnsureFrameForTextNode(nsGenericDOMDataNode* aContent);
   1.212 +
   1.213 +  // generate the child frames and process bindings
   1.214 +  nsresult GenerateChildFrames(nsIFrame* aFrame);
   1.215 +
   1.216 +  // Should be called when a frame is going to be destroyed and
   1.217 +  // WillDestroyFrameTree hasn't been called yet.
   1.218 +  void NotifyDestroyingFrame(nsIFrame* aFrame);
   1.219 +
   1.220 +  void BeginUpdate();
   1.221 +  void EndUpdate();
   1.222 +  void RecalcQuotesAndCounters();
   1.223 +
   1.224 +  // Gets called when the presshell is destroying itself and also
   1.225 +  // when we tear down our frame tree to reconstruct it
   1.226 +  void WillDestroyFrameTree();
   1.227 +
   1.228 +  // Request to create a continuing frame.  This method never returns null.
   1.229 +  nsIFrame* CreateContinuingFrame(nsPresContext* aPresContext,
   1.230 +                                  nsIFrame*       aFrame,
   1.231 +                                  nsIFrame*       aParentFrame,
   1.232 +                                  bool            aIsFluid = true);
   1.233 +
   1.234 +  // Copy over fixed frames from aParentFrame's prev-in-flow
   1.235 +  nsresult ReplicateFixedFrames(nsPageContentFrame* aParentFrame);
   1.236 +
   1.237 +  // Get the XBL insertion point for a child
   1.238 +  nsIFrame* GetInsertionPoint(nsIContent* aContainer,
   1.239 +                              nsIContent* aChildContent,
   1.240 +                              bool*       aMultiple = nullptr);
   1.241 +
   1.242 +  nsresult CreateListBoxContent(nsPresContext* aPresContext,
   1.243 +                                nsIFrame*       aParentFrame,
   1.244 +                                nsIFrame*       aPrevFrame,
   1.245 +                                nsIContent*     aChild,
   1.246 +                                nsIFrame**      aResult,
   1.247 +                                bool            aIsAppend,
   1.248 +                                bool            aIsScrollbar,
   1.249 +                                nsILayoutHistoryState* aFrameState);
   1.250 +
   1.251 +  // GetInitialContainingBlock() is deprecated in favor of GetRootElementFrame();
   1.252 +  // nsIFrame* GetInitialContainingBlock() { return mRootElementFrame; }
   1.253 +  // This returns the outermost frame for the root element
   1.254 +  nsIFrame* GetRootElementFrame() { return mRootElementFrame; }
   1.255 +  // This returns the frame for the root element that does not
   1.256 +  // have a psuedo-element style
   1.257 +  nsIFrame* GetRootElementStyleFrame() { return mRootElementStyleFrame; }
   1.258 +  nsIFrame* GetPageSequenceFrame() { return mPageSequenceFrame; }
   1.259 +
   1.260 +  // Get the frame that is the parent of the root element.
   1.261 +  nsIFrame* GetDocElementContainingBlock()
   1.262 +    { return mDocElementContainingBlock; }
   1.263 +
   1.264 +private:
   1.265 +  struct FrameConstructionItem;
   1.266 +  class FrameConstructionItemList;
   1.267 +
   1.268 +  nsIFrame* ConstructPageFrame(nsIPresShell*  aPresShell,
   1.269 +                               nsPresContext* aPresContext,
   1.270 +                               nsIFrame*      aParentFrame,
   1.271 +                               nsIFrame*      aPrevPageFrame,
   1.272 +                               nsIFrame*&     aCanvasFrame);
   1.273 +
   1.274 +  void InitAndRestoreFrame (const nsFrameConstructorState& aState,
   1.275 +                            nsIContent*                    aContent,
   1.276 +                            nsIFrame*                      aParentFrame,
   1.277 +                            nsIFrame*                      aNewFrame,
   1.278 +                            bool                           aAllowCounters = true);
   1.279 +
   1.280 +  // aState can be null if not available; it's used as an optimization.
   1.281 +  // XXXbz IsValidSibling is the only caller that doesn't pass a state here!
   1.282 +  already_AddRefed<nsStyleContext>
   1.283 +  ResolveStyleContext(nsIFrame*         aParentFrame,
   1.284 +                      nsIContent*       aContent,
   1.285 +                      nsFrameConstructorState* aState);
   1.286 +  already_AddRefed<nsStyleContext>
   1.287 +  ResolveStyleContext(nsStyleContext* aParentStyleContext,
   1.288 +                      nsIContent* aContent,
   1.289 +                      nsFrameConstructorState* aState);
   1.290 +
   1.291 +  // Add the frame construction items for the given aContent and aParentFrame
   1.292 +  // to the list.  This might add more than one item in some rare cases.
   1.293 +  // If aSuppressWhiteSpaceOptimizations is true, optimizations that
   1.294 +  // may suppress the construction of white-space-only text frames
   1.295 +  // must be skipped for these items and items around them.
   1.296 +  void AddFrameConstructionItems(nsFrameConstructorState& aState,
   1.297 +                                 nsIContent*              aContent,
   1.298 +                                 bool                     aSuppressWhiteSpaceOptimizations,
   1.299 +                                 nsIFrame*                aParentFrame,
   1.300 +                                 FrameConstructionItemList& aItems);
   1.301 +
   1.302 +  // Construct the frames for the document element.  This can return null if the
   1.303 +  // document element is display:none, or if the document element has a
   1.304 +  // not-yet-loaded XBL binding, or if it's an SVG element that's not <svg>.
   1.305 +  nsIFrame* ConstructDocElementFrame(Element*                 aDocElement,
   1.306 +                                     nsILayoutHistoryState*   aFrameState);
   1.307 +
   1.308 +  // Set up our mDocElementContainingBlock correctly for the given root
   1.309 +  // content.
   1.310 +  void SetUpDocElementContainingBlock(nsIContent* aDocElement);
   1.311 +
   1.312 +  /**
   1.313 +   * CreateAttributeContent creates a single content/frame combination for an
   1.314 +   * |attr(foo)| generated content.
   1.315 +   *
   1.316 +   * @param aParentContent the parent content for the generated content
   1.317 +   * @param aParentFrame the parent frame for the generated frame
   1.318 +   * @param aAttrNamespace the namespace of the attribute in question
   1.319 +   * @param aAttrName the localname of the attribute
   1.320 +   * @param aStyleContext the style context to use
   1.321 +   * @param aGeneratedContent the array of generated content to append the
   1.322 +   *                          created content to.
   1.323 +   * @param [out] aNewContent the content node we create
   1.324 +   * @param [out] aNewFrame the new frame we create
   1.325 +   */
   1.326 +  nsresult CreateAttributeContent(nsIContent* aParentContent,
   1.327 +                                  nsIFrame* aParentFrame,
   1.328 +                                  int32_t aAttrNamespace,
   1.329 +                                  nsIAtom* aAttrName,
   1.330 +                                  nsStyleContext* aStyleContext,
   1.331 +                                  nsCOMArray<nsIContent>& aGeneratedContent,
   1.332 +                                  nsIContent** aNewContent,
   1.333 +                                  nsIFrame** aNewFrame);
   1.334 +
   1.335 +  /**
   1.336 +   * Create a text node containing the given string. If aText is non-null
   1.337 +   * then we also set aText to the returned node.
   1.338 +   */
   1.339 +  already_AddRefed<nsIContent> CreateGenConTextNode(nsFrameConstructorState& aState,
   1.340 +                                                    const nsString& aString,
   1.341 +                                                    nsCOMPtr<nsIDOMCharacterData>* aText,
   1.342 +                                                    nsGenConInitializer* aInitializer);
   1.343 +
   1.344 +  /**
   1.345 +   * Create a content node for the given generated content style.
   1.346 +   * The caller takes care of making it SetIsNativeAnonymousRoot, binding it
   1.347 +   * to the document, and creating frames for it.
   1.348 +   * @param aParentContent is the node that has the before/after style
   1.349 +   * @param aStyleContext is the 'before' or 'after' pseudo-element
   1.350 +   * style context
   1.351 +   * @param aContentIndex is the index of the content item to create
   1.352 +   */
   1.353 +  already_AddRefed<nsIContent> CreateGeneratedContent(nsFrameConstructorState& aState,
   1.354 +                                                      nsIContent*     aParentContent,
   1.355 +                                                      nsStyleContext* aStyleContext,
   1.356 +                                                      uint32_t        aContentIndex);
   1.357 +
   1.358 +  // aFrame may be null; this method doesn't use it directly in any case.
   1.359 +  void CreateGeneratedContentItem(nsFrameConstructorState&   aState,
   1.360 +                                  nsIFrame*                  aFrame,
   1.361 +                                  nsIContent*                aContent,
   1.362 +                                  nsStyleContext*            aStyleContext,
   1.363 +                                  nsCSSPseudoElements::Type  aPseudoElement,
   1.364 +                                  FrameConstructionItemList& aItems);
   1.365 +
   1.366 +  // This method can change aFrameList: it can chop off the beginning and put
   1.367 +  // it in aParentFrame while putting the remainder into a ib-split sibling of
   1.368 +  // aParentFrame.  aPrevSibling must be the frame after which aFrameList is to
   1.369 +  // be placed on aParentFrame's principal child list.  It may be null if
   1.370 +  // aFrameList is being added at the beginning of the child list.
   1.371 +  nsresult AppendFramesToParent(nsFrameConstructorState&       aState,
   1.372 +                                nsIFrame*                      aParentFrame,
   1.373 +                                nsFrameItems&                  aFrameList,
   1.374 +                                nsIFrame*                      aPrevSibling,
   1.375 +                                bool                           aIsRecursiveCall = false);
   1.376 +
   1.377 +  // BEGIN TABLE SECTION
   1.378 +  /**
   1.379 +   * Construct an outer table frame.  This is the FrameConstructionData
   1.380 +   * callback used for the job.
   1.381 +   */
   1.382 +  nsIFrame* ConstructTable(nsFrameConstructorState& aState,
   1.383 +                           FrameConstructionItem&   aItem,
   1.384 +                           nsIFrame*                aParentFrame,
   1.385 +                           const nsStyleDisplay*    aDisplay,
   1.386 +                           nsFrameItems&            aFrameItems);
   1.387 +
   1.388 +  /**
   1.389 +   * FrameConstructionData callback for constructing table rows and row groups.
   1.390 +   */
   1.391 +  nsIFrame* ConstructTableRowOrRowGroup(nsFrameConstructorState& aState,
   1.392 +                                        FrameConstructionItem&   aItem,
   1.393 +                                        nsIFrame*                aParentFrame,
   1.394 +                                        const nsStyleDisplay*    aStyleDisplay,
   1.395 +                                        nsFrameItems&            aFrameItems);
   1.396 +
   1.397 +  /**
   1.398 +   * FrameConstructionData callback used for constructing table columns.
   1.399 +   */
   1.400 +  nsIFrame* ConstructTableCol(nsFrameConstructorState& aState,
   1.401 +                              FrameConstructionItem&   aItem,
   1.402 +                              nsIFrame*                aParentFrame,
   1.403 +                              const nsStyleDisplay*    aStyleDisplay,
   1.404 +                              nsFrameItems&            aFrameItems);
   1.405 +
   1.406 +  /**
   1.407 +   * FrameConstructionData callback used for constructing table cells.
   1.408 +   */
   1.409 +  nsIFrame* ConstructTableCell(nsFrameConstructorState& aState,
   1.410 +                               FrameConstructionItem&   aItem,
   1.411 +                               nsIFrame*                aParentFrame,
   1.412 +                               const nsStyleDisplay*    aStyleDisplay,
   1.413 +                               nsFrameItems&            aFrameItems);
   1.414 +
   1.415 +private:
   1.416 +  /* An enum of possible parent types for anonymous table object construction */
   1.417 +  enum ParentType {
   1.418 +    eTypeBlock = 0, /* This includes all non-table-related frames */
   1.419 +    eTypeRow,
   1.420 +    eTypeRowGroup,
   1.421 +    eTypeColGroup,
   1.422 +    eTypeTable,
   1.423 +    eParentTypeCount
   1.424 +  };
   1.425 +
   1.426 +  /* 3 bits is enough to handle our ParentType values */
   1.427 +#define FCDATA_PARENT_TYPE_OFFSET 29
   1.428 +  /* Macro to get the desired parent type out of an mBits member of
   1.429 +     FrameConstructionData */
   1.430 +#define FCDATA_DESIRED_PARENT_TYPE(_bits)           \
   1.431 +  ParentType((_bits) >> FCDATA_PARENT_TYPE_OFFSET)
   1.432 +  /* Macro to create FrameConstructionData bits out of a desired parent type */
   1.433 +#define FCDATA_DESIRED_PARENT_TYPE_TO_BITS(_type)     \
   1.434 +  (((uint32_t)(_type)) << FCDATA_PARENT_TYPE_OFFSET)
   1.435 +
   1.436 +  /* Get the parent type that aParentFrame has. */
   1.437 +  static ParentType GetParentType(nsIFrame* aParentFrame) {
   1.438 +    return GetParentType(aParentFrame->GetType());
   1.439 +  }
   1.440 +
   1.441 +  /* Get the parent type for the given nsIFrame type atom */
   1.442 +  static ParentType GetParentType(nsIAtom* aFrameType);
   1.443 +
   1.444 +  /* A constructor function that just creates an nsIFrame object.  The caller
   1.445 +     is responsible for initializing the object, adding it to frame lists,
   1.446 +     constructing frames for the children, etc.
   1.447 +
   1.448 +     @param nsIPresShell the presshell whose arena should be used to allocate
   1.449 +                         the frame.
   1.450 +     @param nsStyleContext the style context to use for the frame. */
   1.451 +  typedef nsIFrame* (* FrameCreationFunc)(nsIPresShell*, nsStyleContext*);
   1.452 +
   1.453 +  /* A function that can be used to get a FrameConstructionData.  Such
   1.454 +     a function is allowed to return null.
   1.455 +
   1.456 +     @param nsIContent the node for which the frame is being constructed.
   1.457 +     @param nsStyleContext the style context to be used for the frame.
   1.458 +  */
   1.459 +  struct FrameConstructionData;
   1.460 +  typedef const FrameConstructionData*
   1.461 +    (* FrameConstructionDataGetter)(Element*, nsStyleContext*);
   1.462 +
   1.463 +  /* A constructor function that's used for complicated construction tasks.
   1.464 +     This is expected to create the new frame, initialize it, add whatever
   1.465 +     needs to be added to aFrameItems (XXXbz is that really necessary?  Could
   1.466 +     caller add?  Might there be cases when the returned frame or its
   1.467 +     placeholder is not the thing that ends up in aFrameItems?  If not, would
   1.468 +     it be safe to do the add into the frame construction state after
   1.469 +     processing kids?  Look into this as a followup!), process children as
   1.470 +     needed, etc.  It is NOT expected to deal with setting the frame on the
   1.471 +     content.
   1.472 +
   1.473 +     @param aState the frame construction state to use.
   1.474 +     @param aItem the frame construction item to use
   1.475 +     @param aParentFrame the frame to set as the parent of the
   1.476 +                         newly-constructed frame.
   1.477 +     @param aStyleDisplay the display struct from aItem's mStyleContext
   1.478 +     @param aFrameItems the frame list to add the new frame (or its
   1.479 +                        placeholder) to.
   1.480 +     @return the frame that was constructed.  This frame is what the caller
   1.481 +             will set as the frame on the content.  Guaranteed non-null.
   1.482 +  */
   1.483 +  typedef nsIFrame*
   1.484 +    (nsCSSFrameConstructor::* FrameFullConstructor)(nsFrameConstructorState& aState,
   1.485 +                                                    FrameConstructionItem& aItem,
   1.486 +                                                    nsIFrame* aParentFrame,
   1.487 +                                                    const nsStyleDisplay* aStyleDisplay,
   1.488 +                                                    nsFrameItems& aFrameItems);
   1.489 +
   1.490 +  /* Bits that modify the way a FrameConstructionData is handled */
   1.491 +
   1.492 +  /* If the FCDATA_SKIP_FRAMESET bit is set, then the frame created should not
   1.493 +     be set as the primary frame on the content node.  This should only be used
   1.494 +     in very rare cases when we create more than one frame for a given content
   1.495 +     node. */
   1.496 +#define FCDATA_SKIP_FRAMESET 0x1
   1.497 +  /* If the FCDATA_FUNC_IS_DATA_GETTER bit is set, then the mFunc of the
   1.498 +     FrameConstructionData is a getter function that can be used to get the
   1.499 +     actual FrameConstructionData to use. */
   1.500 +#define FCDATA_FUNC_IS_DATA_GETTER 0x2
   1.501 +  /* If the FCDATA_FUNC_IS_FULL_CTOR bit is set, then the FrameConstructionData
   1.502 +     has an mFullConstructor.  In this case, there is no relevant mData or
   1.503 +     mFunc */
   1.504 +#define FCDATA_FUNC_IS_FULL_CTOR 0x4
   1.505 +  /* If FCDATA_DISALLOW_OUT_OF_FLOW is set, do not allow the frame to
   1.506 +     float or be absolutely positioned.  This can also be used with
   1.507 +     FCDATA_FUNC_IS_FULL_CTOR to indicate what the full-constructor
   1.508 +     function will do. */
   1.509 +#define FCDATA_DISALLOW_OUT_OF_FLOW 0x8
   1.510 +  /* If FCDATA_FORCE_NULL_ABSPOS_CONTAINER is set, make sure to push a
   1.511 +     null absolute containing block before processing children for this
   1.512 +     frame.  If this is not set, the frame will be pushed as the
   1.513 +     absolute containing block as needed, based on its style */
   1.514 +#define FCDATA_FORCE_NULL_ABSPOS_CONTAINER 0x10
   1.515 +  /* If FCDATA_WRAP_KIDS_IN_BLOCKS is set, the inline kids of the frame
   1.516 +     will be wrapped in blocks.  This is only usable for MathML at the
   1.517 +     moment. */
   1.518 +#define FCDATA_WRAP_KIDS_IN_BLOCKS 0x20
   1.519 +  /* If FCDATA_SUPPRESS_FRAME is set, no frame should be created for the
   1.520 +     content.  If this bit is set, nothing else in the struct needs to be
   1.521 +     set. */
   1.522 +#define FCDATA_SUPPRESS_FRAME 0x40
   1.523 +  /* If FCDATA_MAY_NEED_SCROLLFRAME is set, the new frame should be wrapped in
   1.524 +     a scrollframe if its overflow type so requires. */
   1.525 +#define FCDATA_MAY_NEED_SCROLLFRAME 0x80
   1.526 +#ifdef MOZ_XUL
   1.527 +  /* If FCDATA_IS_POPUP is set, the new frame is a XUL popup frame.  These need
   1.528 +     some really weird special handling.  */
   1.529 +#define FCDATA_IS_POPUP 0x100
   1.530 +#endif /* MOZ_XUL */
   1.531 +  /* If FCDATA_SKIP_ABSPOS_PUSH is set, don't push this frame as an
   1.532 +     absolute containing block, no matter what its style says. */
   1.533 +#define FCDATA_SKIP_ABSPOS_PUSH 0x200
   1.534 +  /* If FCDATA_DISALLOW_GENERATED_CONTENT is set, then don't allow generated
   1.535 +     content when processing kids of this frame.  This should not be used with
   1.536 +     FCDATA_FUNC_IS_FULL_CTOR */
   1.537 +#define FCDATA_DISALLOW_GENERATED_CONTENT 0x400
   1.538 +  /* If FCDATA_IS_TABLE_PART is set, then the frame is some sort of
   1.539 +     table-related thing and we should not attempt to fetch a table-cell parent
   1.540 +     for it if it's inside another table-related frame. */
   1.541 +#define FCDATA_IS_TABLE_PART 0x800
   1.542 +  /* If FCDATA_IS_INLINE is set, then the frame is a non-replaced CSS
   1.543 +     inline box. */
   1.544 +#define FCDATA_IS_INLINE 0x1000
   1.545 +  /* If FCDATA_IS_LINE_PARTICIPANT is set, the frame is something that will
   1.546 +     return true for IsFrameOfType(nsIFrame::eLineParticipant) */
   1.547 +#define FCDATA_IS_LINE_PARTICIPANT 0x2000
   1.548 +  /* If FCDATA_IS_LINE_BREAK is set, the frame is something that will
   1.549 +     induce a line break boundary before and after itself. */
   1.550 +#define FCDATA_IS_LINE_BREAK 0x4000
   1.551 +  /* If FCDATA_ALLOW_BLOCK_STYLES is set, allow block styles when processing
   1.552 +     children.  This should not be used with FCDATA_FUNC_IS_FULL_CTOR. */
   1.553 +#define FCDATA_ALLOW_BLOCK_STYLES 0x8000
   1.554 +  /* If FCDATA_USE_CHILD_ITEMS is set, then use the mChildItems in the relevant
   1.555 +     FrameConstructionItem instead of trying to process the content's children.
   1.556 +     This can be used with or without FCDATA_FUNC_IS_FULL_CTOR.
   1.557 +     The child items might still need table pseudo processing. */
   1.558 +#define FCDATA_USE_CHILD_ITEMS 0x10000
   1.559 +  /* If FCDATA_FORCED_NON_SCROLLABLE_BLOCK is set, then this block
   1.560 +     would have been scrollable but has been forced to be
   1.561 +     non-scrollable due to being in a paginated context. */
   1.562 +#define FCDATA_FORCED_NON_SCROLLABLE_BLOCK 0x20000
   1.563 +  /* If FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, then create a
   1.564 +     block formatting context wrapper around the kids of this frame
   1.565 +     using the FrameConstructionData's mPseudoAtom for its anonymous
   1.566 +     box type. */
   1.567 +#define FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS 0x40000
   1.568 +  /* If FCDATA_IS_SVG_TEXT is set, then this text frame is a descendant of
   1.569 +     an SVG text frame. */
   1.570 +#define FCDATA_IS_SVG_TEXT 0x80000
   1.571 +
   1.572 +  /* Structure representing information about how a frame should be
   1.573 +     constructed.  */
   1.574 +  struct FrameConstructionData {
   1.575 +    // Flag bits that can modify the way the construction happens
   1.576 +    uint32_t mBits;
   1.577 +    // We have exactly one of three types of functions, so use a union for
   1.578 +    // better cache locality for the ones that aren't pointer-to-member.  That
   1.579 +    // one needs to be separate, because we can't cast between it and the
   1.580 +    // others and hence wouldn't be able to initialize the union without a
   1.581 +    // constructor and all the resulting generated code.  See documentation
   1.582 +    // above for FrameCreationFunc, FrameConstructionDataGetter, and
   1.583 +    // FrameFullConstructor to see what the functions would do.
   1.584 +    union Func {
   1.585 +      FrameCreationFunc mCreationFunc;
   1.586 +      FrameConstructionDataGetter mDataGetter;
   1.587 +    } mFunc;
   1.588 +    FrameFullConstructor mFullConstructor;
   1.589 +    // For cases when FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, the
   1.590 +    // anonymous box type to use for that wrapper.
   1.591 +    nsICSSAnonBoxPseudo * const * const mAnonBoxPseudo;
   1.592 +  };
   1.593 +
   1.594 +  /* Structure representing a mapping of an atom to a FrameConstructionData.
   1.595 +     This can be used with non-static atoms, assuming that the nsIAtom* is
   1.596 +     stored somewhere that this struct can point to (that is, a static
   1.597 +     nsIAtom*) and that it's allocated before the struct is ever used. */
   1.598 +  struct FrameConstructionDataByTag {
   1.599 +    // Pointer to nsIAtom* is used because we want to initialize this
   1.600 +    // statically, so before our atom tables are set up.
   1.601 +    const nsIAtom * const * const mTag;
   1.602 +    const FrameConstructionData mData;
   1.603 +  };
   1.604 +
   1.605 +  /* Structure representing a mapping of an integer to a
   1.606 +     FrameConstructionData. There are no magic integer values here. */
   1.607 +  struct FrameConstructionDataByInt {
   1.608 +    /* Could be used for display or whatever else */
   1.609 +    const int32_t mInt;
   1.610 +    const FrameConstructionData mData;
   1.611 +  };
   1.612 +
   1.613 +  /* Structure that has a FrameConstructionData and style context pseudo-type
   1.614 +     for a table pseudo-frame */
   1.615 +  struct PseudoParentData {
   1.616 +    const FrameConstructionData mFCData;
   1.617 +    nsICSSAnonBoxPseudo * const * const mPseudoType;
   1.618 +  };
   1.619 +  /* Array of such structures that we use to properly construct table
   1.620 +     pseudo-frames as needed */
   1.621 +  static const PseudoParentData sPseudoParentData[eParentTypeCount];
   1.622 +
   1.623 +  /* A function that takes an integer, content, style context, and array of
   1.624 +     FrameConstructionDataByInts and finds the appropriate frame construction
   1.625 +     data to use and returns it.  This can return null if none of the integers
   1.626 +     match or if the matching integer has a FrameConstructionDataGetter that
   1.627 +     returns null. */
   1.628 +  static const FrameConstructionData*
   1.629 +    FindDataByInt(int32_t aInt, Element* aElement,
   1.630 +                  nsStyleContext* aStyleContext,
   1.631 +                  const FrameConstructionDataByInt* aDataPtr,
   1.632 +                  uint32_t aDataLength);
   1.633 +
   1.634 +  /* A function that takes a tag, content, style context, and array of
   1.635 +     FrameConstructionDataByTags and finds the appropriate frame construction
   1.636 +     data to use and returns it.  This can return null if none of the tags
   1.637 +     match or if the matching tag has a FrameConstructionDataGetter that
   1.638 +     returns null. */
   1.639 +  static const FrameConstructionData*
   1.640 +    FindDataByTag(nsIAtom* aTag, Element* aElement,
   1.641 +                  nsStyleContext* aStyleContext,
   1.642 +                  const FrameConstructionDataByTag* aDataPtr,
   1.643 +                  uint32_t aDataLength);
   1.644 +
   1.645 +  /* A class representing a list of FrameConstructionItems */
   1.646 +  class FrameConstructionItemList {
   1.647 +  public:
   1.648 +    FrameConstructionItemList() :
   1.649 +      mInlineCount(0),
   1.650 +      mBlockCount(0),
   1.651 +      mLineParticipantCount(0),
   1.652 +      mItemCount(0),
   1.653 +      mLineBoundaryAtStart(false),
   1.654 +      mLineBoundaryAtEnd(false),
   1.655 +      mParentHasNoXBLChildren(false),
   1.656 +      mTriedConstructingFrames(false)
   1.657 +    {
   1.658 +      PR_INIT_CLIST(&mItems);
   1.659 +      memset(mDesiredParentCounts, 0, sizeof(mDesiredParentCounts));
   1.660 +    }
   1.661 +
   1.662 +    ~FrameConstructionItemList() {
   1.663 +      PRCList* cur = PR_NEXT_LINK(&mItems);
   1.664 +      while (cur != &mItems) {
   1.665 +        PRCList* next = PR_NEXT_LINK(cur);
   1.666 +        delete ToItem(cur);
   1.667 +        cur = next;
   1.668 +      }
   1.669 +
   1.670 +      // Leaves our mItems pointing to deleted memory in both directions,
   1.671 +      // but that's OK at this point.
   1.672 +
   1.673 +      // Create the undisplayed entries for our mUndisplayedItems, if any, but
   1.674 +      // only if we have tried constructing frames for this item list.  If we
   1.675 +      // haven't, then we're just throwing it away and will probably try again.
   1.676 +      if (!mUndisplayedItems.IsEmpty() && mTriedConstructingFrames) {
   1.677 +        // We could store the frame manager in a member, but just
   1.678 +        // getting it off the style context is not too bad.
   1.679 +        nsFrameManager *mgr =
   1.680 +          mUndisplayedItems[0].mStyleContext->PresContext()->FrameManager();
   1.681 +        for (uint32_t i = 0; i < mUndisplayedItems.Length(); ++i) {
   1.682 +          UndisplayedItem& item = mUndisplayedItems[i];
   1.683 +          mgr->SetUndisplayedContent(item.mContent, item.mStyleContext);
   1.684 +        }
   1.685 +      }
   1.686 +    }
   1.687 +
   1.688 +    void SetLineBoundaryAtStart(bool aBoundary) { mLineBoundaryAtStart = aBoundary; }
   1.689 +    void SetLineBoundaryAtEnd(bool aBoundary) { mLineBoundaryAtEnd = aBoundary; }
   1.690 +    void SetParentHasNoXBLChildren(bool aHasNoXBLChildren) {
   1.691 +      mParentHasNoXBLChildren = aHasNoXBLChildren;
   1.692 +    }
   1.693 +    void SetTriedConstructingFrames() { mTriedConstructingFrames = true; }
   1.694 +    bool HasLineBoundaryAtStart() { return mLineBoundaryAtStart; }
   1.695 +    bool HasLineBoundaryAtEnd() { return mLineBoundaryAtEnd; }
   1.696 +    bool ParentHasNoXBLChildren() { return mParentHasNoXBLChildren; }
   1.697 +    bool IsEmpty() const { return PR_CLIST_IS_EMPTY(&mItems); }
   1.698 +    bool AnyItemsNeedBlockParent() const { return mLineParticipantCount != 0; }
   1.699 +    bool AreAllItemsInline() const { return mInlineCount == mItemCount; }
   1.700 +    bool AreAllItemsBlock() const { return mBlockCount == mItemCount; }
   1.701 +    bool AllWantParentType(ParentType aDesiredParentType) const {
   1.702 +      return mDesiredParentCounts[aDesiredParentType] == mItemCount;
   1.703 +    }
   1.704 +
   1.705 +    // aSuppressWhiteSpaceOptimizations is true if optimizations that
   1.706 +    // skip constructing whitespace frames for this item or items
   1.707 +    // around it cannot be performed.
   1.708 +    FrameConstructionItem* AppendItem(const FrameConstructionData* aFCData,
   1.709 +                                      nsIContent* aContent,
   1.710 +                                      nsIAtom* aTag,
   1.711 +                                      int32_t aNameSpaceID,
   1.712 +                                      PendingBinding* aPendingBinding,
   1.713 +                                      already_AddRefed<nsStyleContext>&& aStyleContext,
   1.714 +                                      bool aSuppressWhiteSpaceOptimizations,
   1.715 +                                      nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren)
   1.716 +    {
   1.717 +      FrameConstructionItem* item =
   1.718 +        new FrameConstructionItem(aFCData, aContent, aTag, aNameSpaceID,
   1.719 +                                  aPendingBinding, aStyleContext,
   1.720 +                                  aSuppressWhiteSpaceOptimizations,
   1.721 +                                  aAnonChildren);
   1.722 +      PR_APPEND_LINK(item, &mItems);
   1.723 +      ++mItemCount;
   1.724 +      ++mDesiredParentCounts[item->DesiredParentType()];
   1.725 +      return item;
   1.726 +    }
   1.727 +
   1.728 +    void AppendUndisplayedItem(nsIContent* aContent,
   1.729 +                               nsStyleContext* aStyleContext) {
   1.730 +      mUndisplayedItems.AppendElement(UndisplayedItem(aContent, aStyleContext));
   1.731 +    }
   1.732 +
   1.733 +    void InlineItemAdded() { ++mInlineCount; }
   1.734 +    void BlockItemAdded() { ++mBlockCount; }
   1.735 +    void LineParticipantItemAdded() { ++mLineParticipantCount; }
   1.736 +
   1.737 +    class Iterator;
   1.738 +    friend class Iterator;
   1.739 +
   1.740 +    class Iterator {
   1.741 +    public:
   1.742 +      Iterator(FrameConstructionItemList& list) :
   1.743 +        mCurrent(PR_NEXT_LINK(&list.mItems)),
   1.744 +        mEnd(&list.mItems),
   1.745 +        mList(list)
   1.746 +      {}
   1.747 +      Iterator(const Iterator& aOther) :
   1.748 +        mCurrent(aOther.mCurrent),
   1.749 +        mEnd(aOther.mEnd),
   1.750 +        mList(aOther.mList)
   1.751 +      {}
   1.752 +
   1.753 +      bool operator==(const Iterator& aOther) const {
   1.754 +        NS_ASSERTION(mEnd == aOther.mEnd, "Iterators for different lists?");
   1.755 +        return mCurrent == aOther.mCurrent;
   1.756 +      }
   1.757 +      bool operator!=(const Iterator& aOther) const {
   1.758 +        return !(*this == aOther);
   1.759 +      }
   1.760 +      Iterator& operator=(const Iterator& aOther) {
   1.761 +        NS_ASSERTION(mEnd == aOther.mEnd, "Iterators for different lists?");
   1.762 +        mCurrent = aOther.mCurrent;
   1.763 +        return *this;
   1.764 +      }
   1.765 +
   1.766 +      FrameConstructionItemList* List() {
   1.767 +        return &mList;
   1.768 +      }
   1.769 +
   1.770 +      operator FrameConstructionItem& () {
   1.771 +        return item();
   1.772 +      }
   1.773 +
   1.774 +      FrameConstructionItem& item() {
   1.775 +        return *FrameConstructionItemList::ToItem(mCurrent);
   1.776 +      }
   1.777 +      bool IsDone() const { return mCurrent == mEnd; }
   1.778 +      bool AtStart() const { return mCurrent == PR_NEXT_LINK(mEnd); }
   1.779 +      void Next() {
   1.780 +        NS_ASSERTION(!IsDone(), "Should have checked IsDone()!");
   1.781 +        mCurrent = PR_NEXT_LINK(mCurrent);
   1.782 +      }
   1.783 +      void Prev() {
   1.784 +        NS_ASSERTION(!AtStart(), "Should have checked AtStart()!");
   1.785 +        mCurrent = PR_PREV_LINK(mCurrent);
   1.786 +      }
   1.787 +      void SetToEnd() { mCurrent = mEnd; }
   1.788 +
   1.789 +      // Skip over all items that want a parent type different from the given
   1.790 +      // one.  Return whether the iterator is done after doing that.  The
   1.791 +      // iterator must not be done when this is called.
   1.792 +      inline bool SkipItemsWantingParentType(ParentType aParentType);
   1.793 +
   1.794 +      // Skip over non-replaced inline frames and positioned frames.
   1.795 +      // Return whether the iterator is done after doing that.
   1.796 +      // The iterator must not be done when this is called.
   1.797 +      inline bool SkipItemsThatNeedAnonFlexItem(
   1.798 +        const nsFrameConstructorState& aState);
   1.799 +
   1.800 +      // Skip to the first frame that is a non-replaced inline or is
   1.801 +      // positioned.  Return whether the iterator is done after doing that.
   1.802 +      // The iterator must not be done when this is called.
   1.803 +      inline bool SkipItemsThatDontNeedAnonFlexItem(
   1.804 +        const nsFrameConstructorState& aState);
   1.805 +
   1.806 +      // Skip over whitespace.  Return whether the iterator is done after doing
   1.807 +      // that.  The iterator must not be done, and must be pointing to a
   1.808 +      // whitespace item when this is called.
   1.809 +      inline bool SkipWhitespace(nsFrameConstructorState& aState);
   1.810 +
   1.811 +      // Remove the item pointed to by this iterator from its current list and
   1.812 +      // Append it to aTargetList.  This iterator is advanced to point to the
   1.813 +      // next item in its list.  aIter must not be done.  aOther must not be
   1.814 +      // the list this iterator is iterating over..
   1.815 +      void AppendItemToList(FrameConstructionItemList& aTargetList);
   1.816 +
   1.817 +      // As above, but moves all items starting with this iterator until we
   1.818 +      // get to aEnd; the item pointed to by aEnd is not stolen.  This method
   1.819 +      // might have optimizations over just looping and doing StealItem for
   1.820 +      // some special cases.  After this method returns, this iterator will
   1.821 +      // point to the item aEnd points to now; aEnd is not modified.
   1.822 +      // aTargetList must not be the list this iterator is iterating over.
   1.823 +      void AppendItemsToList(const Iterator& aEnd,
   1.824 +                             FrameConstructionItemList& aTargetList);
   1.825 +
   1.826 +      // Insert aItem in this iterator's list right before the item pointed to
   1.827 +      // by this iterator.  After the insertion, this iterator will continue to
   1.828 +      // point to the item it now points to (the one just after the
   1.829 +      // newly-inserted item).  This iterator is allowed to be done; in that
   1.830 +      // case this call just appends the given item to the list.
   1.831 +      void InsertItem(FrameConstructionItem* aItem);
   1.832 +
   1.833 +      // Delete the items between this iterator and aEnd, including the item
   1.834 +      // this iterator currently points to but not including the item pointed
   1.835 +      // to by aEnd.  When this returns, this iterator will point to the same
   1.836 +      // item as aEnd.  This iterator must not equal aEnd when this method is
   1.837 +      // called.
   1.838 +      void DeleteItemsTo(const Iterator& aEnd);
   1.839 +
   1.840 +    private:
   1.841 +      PRCList* mCurrent;
   1.842 +      PRCList* mEnd;
   1.843 +      FrameConstructionItemList& mList;
   1.844 +    };
   1.845 +
   1.846 +  private:
   1.847 +    static FrameConstructionItem* ToItem(PRCList* item) {
   1.848 +      return static_cast<FrameConstructionItem*>(item);
   1.849 +    }
   1.850 +
   1.851 +    struct UndisplayedItem {
   1.852 +      UndisplayedItem(nsIContent* aContent, nsStyleContext* aStyleContext) :
   1.853 +        mContent(aContent), mStyleContext(aStyleContext)
   1.854 +      {}
   1.855 +
   1.856 +      nsIContent * const mContent;
   1.857 +      nsRefPtr<nsStyleContext> mStyleContext;
   1.858 +    };
   1.859 +
   1.860 +    // Adjust our various counts for aItem being added or removed.  aDelta
   1.861 +    // should be either +1 or -1 depending on which is happening.
   1.862 +    void AdjustCountsForItem(FrameConstructionItem* aItem, int32_t aDelta);
   1.863 +
   1.864 +    PRCList mItems;
   1.865 +    uint32_t mInlineCount;
   1.866 +    uint32_t mBlockCount;
   1.867 +    uint32_t mLineParticipantCount;
   1.868 +    uint32_t mItemCount;
   1.869 +    uint32_t mDesiredParentCounts[eParentTypeCount];
   1.870 +    // True if there is guaranteed to be a line boundary before the
   1.871 +    // frames created by these items
   1.872 +    bool mLineBoundaryAtStart;
   1.873 +    // True if there is guaranteed to be a line boundary after the
   1.874 +    // frames created by these items
   1.875 +    bool mLineBoundaryAtEnd;
   1.876 +    // True if the parent is guaranteed to have no XBL anonymous children
   1.877 +    bool mParentHasNoXBLChildren;
   1.878 +    // True if we have tried constructing frames from this list
   1.879 +    bool mTriedConstructingFrames;
   1.880 +
   1.881 +    nsTArray<UndisplayedItem> mUndisplayedItems;
   1.882 +  };
   1.883 +
   1.884 +  typedef FrameConstructionItemList::Iterator FCItemIterator;
   1.885 +
   1.886 +  /* A struct representing an item for which frames might need to be
   1.887 +   * constructed.  This contains all the information needed to construct the
   1.888 +   * frame other than the parent frame and whatever would be stored in the
   1.889 +   * frame constructor state. */
   1.890 +  struct FrameConstructionItem : public PRCList {
   1.891 +    // No need to PR_INIT_CLIST in the constructor because the only
   1.892 +    // place that creates us immediately appends us.
   1.893 +    FrameConstructionItem(const FrameConstructionData* aFCData,
   1.894 +                          nsIContent* aContent,
   1.895 +                          nsIAtom* aTag,
   1.896 +                          int32_t aNameSpaceID,
   1.897 +                          PendingBinding* aPendingBinding,
   1.898 +                          already_AddRefed<nsStyleContext>& aStyleContext,
   1.899 +                          bool aSuppressWhiteSpaceOptimizations,
   1.900 +                          nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren) :
   1.901 +      mFCData(aFCData), mContent(aContent), mTag(aTag),
   1.902 +      mNameSpaceID(aNameSpaceID),
   1.903 +      mPendingBinding(aPendingBinding), mStyleContext(aStyleContext),
   1.904 +      mSuppressWhiteSpaceOptimizations(aSuppressWhiteSpaceOptimizations),
   1.905 +      mIsText(false), mIsGeneratedContent(false),
   1.906 +      mIsAnonymousContentCreatorContent(false),
   1.907 +      mIsRootPopupgroup(false), mIsAllInline(false), mIsBlock(false),
   1.908 +      mHasInlineEnds(false), mIsPopup(false),
   1.909 +      mIsLineParticipant(false), mIsForSVGAElement(false)
   1.910 +    {
   1.911 +      if (aAnonChildren) {
   1.912 +        NS_ASSERTION(!(mFCData->mBits & FCDATA_FUNC_IS_FULL_CTOR) ||
   1.913 +                     mFCData->mFullConstructor ==
   1.914 +                       &nsCSSFrameConstructor::ConstructInline,
   1.915 +                     "This is going to fail");
   1.916 +        NS_ASSERTION(!(mFCData->mBits & FCDATA_USE_CHILD_ITEMS),
   1.917 +                     "nsIAnonymousContentCreator::CreateAnonymousContent "
   1.918 +                     "implementations should not output a list where the "
   1.919 +                     "items have children in this case");
   1.920 +        mAnonChildren.SwapElements(*aAnonChildren);
   1.921 +      }
   1.922 +    }
   1.923 +    ~FrameConstructionItem() {
   1.924 +      if (mIsGeneratedContent) {
   1.925 +        mContent->UnbindFromTree();
   1.926 +        NS_RELEASE(mContent);
   1.927 +      }
   1.928 +    }
   1.929 +
   1.930 +    ParentType DesiredParentType() {
   1.931 +      return FCDATA_DESIRED_PARENT_TYPE(mFCData->mBits);
   1.932 +    }
   1.933 +
   1.934 +    // Indicates whether (when in a flexbox container) this item needs to be
   1.935 +    // wrapped in an anonymous block.
   1.936 +    bool NeedsAnonFlexItem(const nsFrameConstructorState& aState);
   1.937 +
   1.938 +    // Don't call this unless the frametree really depends on the answer!
   1.939 +    // Especially so for generated content, where we don't want to reframe
   1.940 +    // things.
   1.941 +    bool IsWhitespace(nsFrameConstructorState& aState) const;
   1.942 +
   1.943 +    bool IsLineBoundary() const {
   1.944 +      return mIsBlock || (mFCData->mBits & FCDATA_IS_LINE_BREAK);
   1.945 +    }
   1.946 +
   1.947 +    // The FrameConstructionData to use.
   1.948 +    const FrameConstructionData* mFCData;
   1.949 +    // The nsIContent node to use when initializing the new frame.
   1.950 +    nsIContent* mContent;
   1.951 +    // The XBL-resolved tag name to use for frame construction.
   1.952 +    nsIAtom* mTag;
   1.953 +    // The XBL-resolved namespace to use for frame construction.
   1.954 +    int32_t mNameSpaceID;
   1.955 +    // The PendingBinding for this frame construction item, if any.  May be
   1.956 +    // null.  We maintain a list of PendingBindings in the frame construction
   1.957 +    // state in the order in which AddToAttachedQueue should be called on them:
   1.958 +    // depth-first, post-order traversal order.  Since we actually traverse the
   1.959 +    // DOM in a mix of breadth-first and depth-first, it is the responsibility
   1.960 +    // of whoever constructs FrameConstructionItem kids of a given
   1.961 +    // FrameConstructionItem to push its mPendingBinding as the current
   1.962 +    // insertion point before doing so and pop it afterward.
   1.963 +    PendingBinding* mPendingBinding;
   1.964 +    // The style context to use for creating the new frame.
   1.965 +    nsRefPtr<nsStyleContext> mStyleContext;
   1.966 +    // Whether optimizations to skip constructing textframes around
   1.967 +    // this content need to be suppressed.
   1.968 +    bool mSuppressWhiteSpaceOptimizations;
   1.969 +    // Whether this is a text content item.
   1.970 +    bool mIsText;
   1.971 +    // Whether this is a generated content container.
   1.972 +    // If it is, mContent is a strong pointer.
   1.973 +    bool mIsGeneratedContent;
   1.974 +    // Whether this is an item for nsIAnonymousContentCreator content.
   1.975 +    bool mIsAnonymousContentCreatorContent;
   1.976 +    // Whether this is an item for the root popupgroup.
   1.977 +    bool mIsRootPopupgroup;
   1.978 +    // Whether construction from this item will create only frames that are
   1.979 +    // IsInlineOutside() in the principal child list.  This is not precise, but
   1.980 +    // conservative: if true the frames will really be inline, whereas if false
   1.981 +    // they might still all be inline.
   1.982 +    bool mIsAllInline;
   1.983 +    // Whether construction from this item will create only frames that are
   1.984 +    // IsBlockOutside() in the principal child list.  This is not precise, but
   1.985 +    // conservative: if true the frames will really be blocks, whereas if false
   1.986 +    // they might still be blocks (and in particular, out-of-flows that didn't
   1.987 +    // find a containing block).
   1.988 +    bool mIsBlock;
   1.989 +    // Whether construction from this item will give leading and trailing
   1.990 +    // inline frames.  This is equal to mIsAllInline, except for inline frame
   1.991 +    // items, where it's always true, whereas mIsAllInline might be false due
   1.992 +    // to {ib} splits.
   1.993 +    bool mHasInlineEnds;
   1.994 +    // Whether construction from this item will create a popup that needs to
   1.995 +    // go into the global popup items.
   1.996 +    bool mIsPopup;
   1.997 +    // Whether this item should be treated as a line participant
   1.998 +    bool mIsLineParticipant;
   1.999 +    // Whether this item is for an SVG <a> element
  1.1000 +    bool mIsForSVGAElement;
  1.1001 +
  1.1002 +    // Child frame construction items.
  1.1003 +    FrameConstructionItemList mChildItems;
  1.1004 +
  1.1005 +    // ContentInfo list for children that have yet to have
  1.1006 +    // FrameConstructionItem objects created for them. This exists because
  1.1007 +    // AddFrameConstructionItemsInternal needs a valid frame, but in the case
  1.1008 +    // that nsIAnonymousContentCreator::CreateAnonymousContent returns items
  1.1009 +    // that have their own children (so we have a tree of ContentInfo objects
  1.1010 +    // rather than a flat list) we don't yet have a frame to provide to
  1.1011 +    // AddFrameConstructionItemsInternal in order to create the items for the
  1.1012 +    // grandchildren. That prevents FrameConstructionItems from being created
  1.1013 +    // for these grandchildren (and any descendants that they may have),
  1.1014 +    // otherwise they could have been added to the mChildItems member of their
  1.1015 +    // parent FrameConstructionItem. As it is, the grandchildren ContentInfo
  1.1016 +    // list has to be stored in this mAnonChildren member in order to delay
  1.1017 +    // construction of the FrameConstructionItems for the grandchildren until
  1.1018 +    // a frame has been created for their parent item.
  1.1019 +    nsTArray<nsIAnonymousContentCreator::ContentInfo> mAnonChildren;
  1.1020 +
  1.1021 +  private:
  1.1022 +    FrameConstructionItem(const FrameConstructionItem& aOther) MOZ_DELETE; /* not implemented */
  1.1023 +  };
  1.1024 +
  1.1025 +  /**
  1.1026 +   * Function to create the anonymous flex items that we need.
  1.1027 +   * If aParentFrame is not a nsFlexContainerFrame then this method is a NOP.
  1.1028 +   * @param aItems the child frame construction items before pseudo creation
  1.1029 +   * @param aParentFrame the parent frame
  1.1030 +   */
  1.1031 +  void CreateNeededAnonFlexItems(nsFrameConstructorState& aState,
  1.1032 +                                    FrameConstructionItemList& aItems,
  1.1033 +                                    nsIFrame* aParentFrame);
  1.1034 +
  1.1035 +  /**
  1.1036 +   * Function to create the table pseudo items we need.
  1.1037 +   * @param aItems the child frame construction items before pseudo creation
  1.1038 +   * @param aParentFrame the parent frame we're creating pseudos for
  1.1039 +   */
  1.1040 +  inline void CreateNeededTablePseudos(nsFrameConstructorState& aState,
  1.1041 +                                       FrameConstructionItemList& aItems,
  1.1042 +                                       nsIFrame* aParentFrame);
  1.1043 +
  1.1044 +  /**
  1.1045 +   * Function to adjust aParentFrame to deal with captions.
  1.1046 +   * @param aParentFrame the frame we think should be the parent.  This will be
  1.1047 +   *        adjusted to point to the right parent frame.
  1.1048 +   * @param aFCData the FrameConstructionData that would be used for frame
  1.1049 +   *        construction.
  1.1050 +   * @param aStyleContext the style context for aChildContent
  1.1051 +   */
  1.1052 +  // XXXbz this function should really go away once we rework pseudo-frame
  1.1053 +  // handling to be better. This should simply be part of the job of
  1.1054 +  // GetGeometricParent, and stuff like the frameitems and parent frame should
  1.1055 +  // be kept track of in the state...
  1.1056 +  void AdjustParentFrame(nsIFrame* &                  aParentFrame,
  1.1057 +                         const FrameConstructionData* aFCData,
  1.1058 +                         nsStyleContext*              aStyleContext);
  1.1059 +
  1.1060 +  // END TABLE SECTION
  1.1061 +
  1.1062 +protected:
  1.1063 +  static nsIFrame* CreatePlaceholderFrameFor(nsIPresShell*    aPresShell,
  1.1064 +                                             nsIContent*      aContent,
  1.1065 +                                             nsIFrame*        aFrame,
  1.1066 +                                             nsStyleContext*  aStyleContext,
  1.1067 +                                             nsIFrame*        aParentFrame,
  1.1068 +                                             nsIFrame*        aPrevInFlow,
  1.1069 +                                             nsFrameState     aTypeBit);
  1.1070 +
  1.1071 +private:
  1.1072 +  // ConstructSelectFrame puts the new frame in aFrameItems and
  1.1073 +  // handles the kids of the select.
  1.1074 +  nsIFrame* ConstructSelectFrame(nsFrameConstructorState& aState,
  1.1075 +                                 FrameConstructionItem&   aItem,
  1.1076 +                                 nsIFrame*                aParentFrame,
  1.1077 +                                 const nsStyleDisplay*    aStyleDisplay,
  1.1078 +                                 nsFrameItems&            aFrameItems);
  1.1079 +
  1.1080 +  // ConstructFieldSetFrame puts the new frame in aFrameItems and
  1.1081 +  // handles the kids of the fieldset
  1.1082 +  nsIFrame* ConstructFieldSetFrame(nsFrameConstructorState& aState,
  1.1083 +                                   FrameConstructionItem&   aItem,
  1.1084 +                                   nsIFrame*                aParentFrame,
  1.1085 +                                   const nsStyleDisplay*    aStyleDisplay,
  1.1086 +                                   nsFrameItems&            aFrameItems);
  1.1087 +
  1.1088 +  // aParentFrame might be null.  If it is, that means it was an
  1.1089 +  // inline frame.
  1.1090 +  static const FrameConstructionData* FindTextData(nsIFrame* aParentFrame);
  1.1091 +
  1.1092 +  void ConstructTextFrame(const FrameConstructionData* aData,
  1.1093 +                          nsFrameConstructorState& aState,
  1.1094 +                          nsIContent*              aContent,
  1.1095 +                          nsIFrame*                aParentFrame,
  1.1096 +                          nsStyleContext*          aStyleContext,
  1.1097 +                          nsFrameItems&            aFrameItems);
  1.1098 +
  1.1099 +  // If aPossibleTextContent is a text node and doesn't have a frame, append a
  1.1100 +  // frame construction item for it to aItems.
  1.1101 +  void AddTextItemIfNeeded(nsFrameConstructorState& aState,
  1.1102 +                           nsIFrame* aParentFrame,
  1.1103 +                           nsIContent* aPossibleTextContent,
  1.1104 +                           FrameConstructionItemList& aItems);
  1.1105 +
  1.1106 +  // If aParentContent's child aContent is a text node and
  1.1107 +  // doesn't have a frame, try to create a frame for it.
  1.1108 +  void ReframeTextIfNeeded(nsIContent* aParentContent,
  1.1109 +                           nsIContent* aContent);
  1.1110 +
  1.1111 +  void AddPageBreakItem(nsIContent* aContent,
  1.1112 +                        nsStyleContext* aMainStyleContext,
  1.1113 +                        FrameConstructionItemList& aItems);
  1.1114 +
  1.1115 +  // Function to find FrameConstructionData for aElement.  Will return
  1.1116 +  // null if aElement is not HTML.
  1.1117 +  // aParentFrame might be null.  If it is, that means it was an
  1.1118 +  // inline frame.
  1.1119 +  static const FrameConstructionData* FindHTMLData(Element* aContent,
  1.1120 +                                                   nsIAtom* aTag,
  1.1121 +                                                   int32_t aNameSpaceID,
  1.1122 +                                                   nsIFrame* aParentFrame,
  1.1123 +                                                   nsStyleContext* aStyleContext);
  1.1124 +  // HTML data-finding helper functions
  1.1125 +  static const FrameConstructionData*
  1.1126 +    FindImgData(Element* aElement, nsStyleContext* aStyleContext);
  1.1127 +  static const FrameConstructionData*
  1.1128 +    FindImgControlData(Element* aElement, nsStyleContext* aStyleContext);
  1.1129 +  static const FrameConstructionData*
  1.1130 +    FindInputData(Element* aElement, nsStyleContext* aStyleContext);
  1.1131 +  static const FrameConstructionData*
  1.1132 +    FindObjectData(Element* aElement, nsStyleContext* aStyleContext);
  1.1133 +  static const FrameConstructionData*
  1.1134 +    FindCanvasData(Element* aElement, nsStyleContext* aStyleContext);
  1.1135 +
  1.1136 +  /* Construct a frame from the given FrameConstructionItem.  This function
  1.1137 +     will handle adding the frame to frame lists, processing children, setting
  1.1138 +     the frame as the primary frame for the item's content, and so forth.
  1.1139 +
  1.1140 +     @param aItem the FrameConstructionItem to use.
  1.1141 +     @param aState the frame construction state to use.
  1.1142 +     @param aParentFrame the frame to set as the parent of the
  1.1143 +                         newly-constructed frame.
  1.1144 +     @param aFrameItems the frame list to add the new frame (or its
  1.1145 +                        placeholder) to.
  1.1146 +  */
  1.1147 +  void ConstructFrameFromItemInternal(FrameConstructionItem& aItem,
  1.1148 +                                      nsFrameConstructorState& aState,
  1.1149 +                                      nsIFrame* aParentFrame,
  1.1150 +                                      nsFrameItems& aFrameItems);
  1.1151 +
  1.1152 +  // possible flags for AddFrameConstructionItemInternal's aFlags argument
  1.1153 +  /* Allow xbl:base to affect the tag/namespace used. */
  1.1154 +#define ITEM_ALLOW_XBL_BASE 0x1
  1.1155 +  /* Allow page-break before and after items to be created if the
  1.1156 +     style asks for them. */
  1.1157 +#define ITEM_ALLOW_PAGE_BREAK 0x2
  1.1158 +  /* The item is a generated content item. */
  1.1159 +#define ITEM_IS_GENERATED_CONTENT 0x4
  1.1160 +  /* The item is within an SVG text block frame. */
  1.1161 +#define ITEM_IS_WITHIN_SVG_TEXT 0x8
  1.1162 +  /* The item allows items to be created for SVG <textPath> children. */
  1.1163 +#define ITEM_ALLOWS_TEXT_PATH_CHILD 0x10
  1.1164 +  /* The item is content created by an nsIAnonymousContentCreator frame */
  1.1165 +#define ITEM_IS_ANONYMOUSCONTENTCREATOR_CONTENT 0x20
  1.1166 +  // The guts of AddFrameConstructionItems
  1.1167 +  // aParentFrame might be null.  If it is, that means it was an
  1.1168 +  // inline frame.
  1.1169 +  void AddFrameConstructionItemsInternal(nsFrameConstructorState& aState,
  1.1170 +                                         nsIContent*              aContent,
  1.1171 +                                         nsIFrame*                aParentFrame,
  1.1172 +                                         nsIAtom*                 aTag,
  1.1173 +                                         int32_t                  aNameSpaceID,
  1.1174 +                                         bool                     aSuppressWhiteSpaceOptimizations,
  1.1175 +                                         nsStyleContext*          aStyleContext,
  1.1176 +                                         uint32_t                 aFlags,
  1.1177 +                                         nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren,
  1.1178 +                                         FrameConstructionItemList& aItems);
  1.1179 +
  1.1180 +  /**
  1.1181 +   * Construct frames for the given item list and parent frame, and put the
  1.1182 +   * resulting frames in aFrameItems.
  1.1183 +   */
  1.1184 +  void ConstructFramesFromItemList(nsFrameConstructorState& aState,
  1.1185 +                                   FrameConstructionItemList& aItems,
  1.1186 +                                   nsIFrame* aParentFrame,
  1.1187 +                                   nsFrameItems& aFrameItems);
  1.1188 +  void ConstructFramesFromItem(nsFrameConstructorState& aState,
  1.1189 +                               FCItemIterator& aItem,
  1.1190 +                               nsIFrame* aParentFrame,
  1.1191 +                               nsFrameItems& aFrameItems);
  1.1192 +  static bool AtLineBoundary(FCItemIterator& aIter);
  1.1193 +
  1.1194 +  nsresult CreateAnonymousFrames(nsFrameConstructorState& aState,
  1.1195 +                                 nsIContent*              aParent,
  1.1196 +                                 nsIFrame*                aParentFrame,
  1.1197 +                                 PendingBinding  *        aPendingBinding,
  1.1198 +                                 nsFrameItems&            aChildItems);
  1.1199 +
  1.1200 +  nsresult GetAnonymousContent(nsIContent* aParent,
  1.1201 +                               nsIFrame* aParentFrame,
  1.1202 +                               nsTArray<nsIAnonymousContentCreator::ContentInfo>& aAnonContent);
  1.1203 +
  1.1204 +//MathML Mod - RBS
  1.1205 +  /**
  1.1206 +   * Takes the frames in aBlockItems and wraps them in a new anonymous block
  1.1207 +   * frame whose content is aContent and whose parent will be aParentFrame.
  1.1208 +   * The anonymous block is added to aNewItems and aBlockItems is cleared.
  1.1209 +   */
  1.1210 +  void FlushAccumulatedBlock(nsFrameConstructorState& aState,
  1.1211 +                             nsIContent* aContent,
  1.1212 +                             nsIFrame* aParentFrame,
  1.1213 +                             nsFrameItems& aBlockItems,
  1.1214 +                             nsFrameItems& aNewItems);
  1.1215 +
  1.1216 +  // Function to find FrameConstructionData for aContent.  Will return
  1.1217 +  // null if aContent is not MathML.
  1.1218 +  static const FrameConstructionData* FindMathMLData(Element* aElement,
  1.1219 +                                                     nsIAtom* aTag,
  1.1220 +                                                     int32_t aNameSpaceID,
  1.1221 +                                                     nsStyleContext* aStyleContext);
  1.1222 +
  1.1223 +  // Function to find FrameConstructionData for aContent.  Will return
  1.1224 +  // null if aContent is not XUL.
  1.1225 +  static const FrameConstructionData* FindXULTagData(Element* aElement,
  1.1226 +                                                     nsIAtom* aTag,
  1.1227 +                                                     int32_t aNameSpaceID,
  1.1228 +                                                     nsStyleContext* aStyleContext);
  1.1229 +  // XUL data-finding helper functions and structures
  1.1230 +#ifdef MOZ_XUL
  1.1231 +  static const FrameConstructionData*
  1.1232 +    FindPopupGroupData(Element* aElement, nsStyleContext* aStyleContext);
  1.1233 +  // sXULTextBoxData used for both labels and descriptions
  1.1234 +  static const FrameConstructionData sXULTextBoxData;
  1.1235 +  static const FrameConstructionData*
  1.1236 +    FindXULLabelData(Element* aElement, nsStyleContext* aStyleContext);
  1.1237 +  static const FrameConstructionData*
  1.1238 +    FindXULDescriptionData(Element* aElement, nsStyleContext* aStyleContext);
  1.1239 +#ifdef XP_MACOSX
  1.1240 +  static const FrameConstructionData*
  1.1241 +    FindXULMenubarData(Element* aElement, nsStyleContext* aStyleContext);
  1.1242 +#endif /* XP_MACOSX */
  1.1243 +  static const FrameConstructionData*
  1.1244 +    FindXULListBoxBodyData(Element* aElement, nsStyleContext* aStyleContext);
  1.1245 +  static const FrameConstructionData*
  1.1246 +    FindXULListItemData(Element* aElement, nsStyleContext* aStyleContext);
  1.1247 +#endif /* MOZ_XUL */
  1.1248 +
  1.1249 +  // Function to find FrameConstructionData for aContent using one of the XUL
  1.1250 +  // display types.  Will return null if aDisplay doesn't have a XUL display
  1.1251 +  // type.  This function performs no other checks, so should only be called if
  1.1252 +  // we know for sure that the content is not something that should get a frame
  1.1253 +  // constructed by tag.
  1.1254 +  static const FrameConstructionData*
  1.1255 +    FindXULDisplayData(const nsStyleDisplay* aDisplay,
  1.1256 +                       Element* aElement,
  1.1257 +                       nsStyleContext* aStyleContext);
  1.1258 +
  1.1259 +  /**
  1.1260 +   * Constructs an outer frame, an anonymous child that wraps its real
  1.1261 +   * children, and its descendant frames.  This is used by both ConstructOuterSVG
  1.1262 +   * and ConstructMarker, which both want an anonymous block child for their
  1.1263 +   * children to go in to.
  1.1264 +   */
  1.1265 +  nsIFrame* ConstructFrameWithAnonymousChild(
  1.1266 +                                  nsFrameConstructorState& aState,
  1.1267 +                                  FrameConstructionItem&   aItem,
  1.1268 +                                  nsIFrame*                aParentFrame,
  1.1269 +                                  const nsStyleDisplay*    aDisplay,
  1.1270 +                                  nsFrameItems&            aFrameItems,
  1.1271 +                                  FrameCreationFunc        aConstructor,
  1.1272 +                                  FrameCreationFunc        aInnerConstructor,
  1.1273 +                                  nsICSSAnonBoxPseudo*     aInnerPseudo,
  1.1274 +                                  bool                     aCandidateRootFrame);
  1.1275 +
  1.1276 +  /**
  1.1277 +   * Construct an nsSVGOuterSVGFrame.
  1.1278 +   */
  1.1279 +  nsIFrame* ConstructOuterSVG(nsFrameConstructorState& aState,
  1.1280 +                              FrameConstructionItem&   aItem,
  1.1281 +                              nsIFrame*                aParentFrame,
  1.1282 +                              const nsStyleDisplay*    aDisplay,
  1.1283 +                              nsFrameItems&            aFrameItems);
  1.1284 +
  1.1285 +  /**
  1.1286 +   * Construct an nsSVGMarkerFrame.
  1.1287 +   */
  1.1288 +  nsIFrame* ConstructMarker(nsFrameConstructorState& aState,
  1.1289 +                            FrameConstructionItem&   aItem,
  1.1290 +                            nsIFrame*                aParentFrame,
  1.1291 +                            const nsStyleDisplay*    aDisplay,
  1.1292 +                            nsFrameItems&            aFrameItems);
  1.1293 +
  1.1294 +  static const FrameConstructionData* FindSVGData(Element* aElement,
  1.1295 +                                                  nsIAtom* aTag,
  1.1296 +                                                  int32_t aNameSpaceID,
  1.1297 +                                                  nsIFrame* aParentFrame,
  1.1298 +                                                  bool aIsWithinSVGText,
  1.1299 +                                                  bool aAllowsTextPathChild,
  1.1300 +                                                  nsStyleContext* aStyleContext);
  1.1301 +
  1.1302 +  /* Not static because it does PropagateScrollToViewport.  If this
  1.1303 +     changes, make this static */
  1.1304 +  const FrameConstructionData*
  1.1305 +    FindDisplayData(const nsStyleDisplay* aDisplay, Element* aElement,
  1.1306 +                    nsIFrame* aParentFrame, nsStyleContext* aStyleContext);
  1.1307 +
  1.1308 +  /**
  1.1309 +   * Construct a scrollable block frame
  1.1310 +   */
  1.1311 +  nsIFrame* ConstructScrollableBlock(nsFrameConstructorState& aState,
  1.1312 +                                     FrameConstructionItem&   aItem,
  1.1313 +                                     nsIFrame*                aParentFrame,
  1.1314 +                                     const nsStyleDisplay*    aDisplay,
  1.1315 +                                     nsFrameItems&            aFrameItems);
  1.1316 +
  1.1317 +  /**
  1.1318 +   * Construct a non-scrollable block frame
  1.1319 +   */
  1.1320 +  nsIFrame* ConstructNonScrollableBlock(nsFrameConstructorState& aState,
  1.1321 +                                        FrameConstructionItem&   aItem,
  1.1322 +                                        nsIFrame*                aParentFrame,
  1.1323 +                                        const nsStyleDisplay*    aDisplay,
  1.1324 +                                        nsFrameItems&            aFrameItems);
  1.1325 +
  1.1326 +  /**
  1.1327 +   * This adds FrameConstructionItem objects to aItemsToConstruct for the
  1.1328 +   * anonymous content returned by an nsIAnonymousContentCreator::
  1.1329 +   * CreateAnonymousContent implementation.
  1.1330 +   */
  1.1331 +  void AddFCItemsForAnonymousContent(
  1.1332 +            nsFrameConstructorState& aState,
  1.1333 +            nsIFrame* aFrame,
  1.1334 +            nsTArray<nsIAnonymousContentCreator::ContentInfo>& aAnonymousItems,
  1.1335 +            FrameConstructionItemList& aItemsToConstruct,
  1.1336 +            uint32_t aExtraFlags = 0);
  1.1337 +
  1.1338 +  /**
  1.1339 +   * Construct the frames for the children of aContent.  "children" is defined
  1.1340 +   * as "whatever FlattenedChildIterator returns for aContent".  This means we're
  1.1341 +   * basically operating on children in the "flattened tree" per sXBL/XBL2.
  1.1342 +   * This method will also handle constructing ::before, ::after,
  1.1343 +   * ::first-letter, and ::first-line frames, as needed and if allowed.
  1.1344 +   *
  1.1345 +   * If the parent is a float containing block, this method will handle pushing
  1.1346 +   * it as the float containing block in aState (so there's no need for callers
  1.1347 +   * to push it themselves).
  1.1348 +   *
  1.1349 +   * @param aState the frame construction state
  1.1350 +   * @param aContent the content node whose children need frames
  1.1351 +   * @param aStyleContext the style context for aContent
  1.1352 +   * @param aFrame the frame to use as the parent frame for the new in-flow
  1.1353 +   *        kids. Note that this must be its own content insertion frame, but
  1.1354 +   *        need not be be the primary frame for aContent.  This frame will be
  1.1355 +   *        pushed as the float containing block, as needed.  aFrame is also
  1.1356 +   *        used to find the parent style context for the kids' style contexts
  1.1357 +   *        (not necessary aFrame's style context).
  1.1358 +   * @param aCanHaveGeneratedContent Whether to allow :before and
  1.1359 +   *        :after styles on the parent.
  1.1360 +   * @param aFrameItems the list in which we should place the in-flow children
  1.1361 +   * @param aAllowBlockStyles Whether to allow first-letter and first-line
  1.1362 +   *        styles on the parent.
  1.1363 +   * @param aPendingBinding Make sure to push this into aState before doing any
  1.1364 +   *        child item construction.
  1.1365 +   * @param aPossiblyLeafFrame if non-null, this should be used for the isLeaf
  1.1366 +   *        test and the anonymous content creation.  If null, aFrame will be
  1.1367 +   *        used.
  1.1368 +   */
  1.1369 +  void ProcessChildren(nsFrameConstructorState& aState,
  1.1370 +                       nsIContent*              aContent,
  1.1371 +                       nsStyleContext*          aStyleContext,
  1.1372 +                       nsIFrame*                aFrame,
  1.1373 +                       const bool               aCanHaveGeneratedContent,
  1.1374 +                       nsFrameItems&            aFrameItems,
  1.1375 +                       const bool               aAllowBlockStyles,
  1.1376 +                       PendingBinding*          aPendingBinding,
  1.1377 +                       nsIFrame*                aPossiblyLeafFrame = nullptr);
  1.1378 +
  1.1379 +  nsIFrame* GetFrameFor(nsIContent* aContent);
  1.1380 +
  1.1381 +  /**
  1.1382 +   * These two functions are used when we start frame creation from a non-root
  1.1383 +   * element. They should recreate the same state that we would have
  1.1384 +   * arrived at if we had built frames from the root frame to aFrame.
  1.1385 +   * Therefore, any calls to PushFloatContainingBlock and
  1.1386 +   * PushAbsoluteContainingBlock during frame construction should get
  1.1387 +   * corresponding logic in these functions.
  1.1388 +   */
  1.1389 +public:
  1.1390 +  enum ContainingBlockType {
  1.1391 +    ABS_POS,
  1.1392 +    FIXED_POS
  1.1393 +  };
  1.1394 +  nsIFrame* GetAbsoluteContainingBlock(nsIFrame* aFrame, ContainingBlockType aType);
  1.1395 +  nsIFrame* GetFloatContainingBlock(nsIFrame* aFrame);
  1.1396 +
  1.1397 +private:
  1.1398 +  nsIContent* PropagateScrollToViewport();
  1.1399 +
  1.1400 +  // Build a scroll frame:
  1.1401 +  //  Calls BeginBuildingScrollFrame, InitAndRestoreFrame, and then FinishBuildingScrollFrame.
  1.1402 +  // @param aNewFrame the created scrollframe --- output only
  1.1403 +  // @param aParentFrame the geometric parent that the scrollframe will have.
  1.1404 +  nsresult
  1.1405 +  BuildScrollFrame(nsFrameConstructorState& aState,
  1.1406 +                   nsIContent*              aContent,
  1.1407 +                   nsStyleContext*          aContentStyle,
  1.1408 +                   nsIFrame*                aScrolledFrame,
  1.1409 +                   nsIFrame*                aParentFrame,
  1.1410 +                   nsIFrame*&               aNewFrame);
  1.1411 +
  1.1412 +  // Builds the initial ScrollFrame
  1.1413 +  already_AddRefed<nsStyleContext>
  1.1414 +  BeginBuildingScrollFrame(nsFrameConstructorState& aState,
  1.1415 +                           nsIContent*              aContent,
  1.1416 +                           nsStyleContext*          aContentStyle,
  1.1417 +                           nsIFrame*                aParentFrame,
  1.1418 +                           nsIAtom*                 aScrolledPseudo,
  1.1419 +                           bool                     aIsRoot,
  1.1420 +                           nsIFrame*&               aNewFrame);
  1.1421 +
  1.1422 +  // Completes the building of the scrollframe:
  1.1423 +  // Creates a view for the scrolledframe and makes it the child of the scrollframe.
  1.1424 +  void
  1.1425 +  FinishBuildingScrollFrame(nsIFrame* aScrollFrame,
  1.1426 +                            nsIFrame* aScrolledFrame);
  1.1427 +
  1.1428 +  // InitializeSelectFrame puts scrollFrame in aFrameItems if aBuildCombobox is false
  1.1429 +  // aBuildCombobox indicates if we are building a combobox that has a dropdown
  1.1430 +  // popup widget or not.
  1.1431 +  nsresult
  1.1432 +  InitializeSelectFrame(nsFrameConstructorState& aState,
  1.1433 +                        nsIFrame*                scrollFrame,
  1.1434 +                        nsIFrame*                scrolledFrame,
  1.1435 +                        nsIContent*              aContent,
  1.1436 +                        nsIFrame*                aParentFrame,
  1.1437 +                        nsStyleContext*          aStyleContext,
  1.1438 +                        bool                     aBuildCombobox,
  1.1439 +                        PendingBinding*          aPendingBinding,
  1.1440 +                        nsFrameItems&            aFrameItems);
  1.1441 +
  1.1442 +  nsresult MaybeRecreateFramesForElement(Element* aElement);
  1.1443 +
  1.1444 +  // If aAsyncInsert is true then a restyle event will be posted to handle the
  1.1445 +  // required ContentInserted call instead of doing it immediately.
  1.1446 +  nsresult RecreateFramesForContent(nsIContent* aContent, bool aAsyncInsert);
  1.1447 +
  1.1448 +  // If removal of aFrame from the frame tree requires reconstruction of some
  1.1449 +  // containing block (either of aFrame or of its parent) due to {ib} splits or
  1.1450 +  // table pseudo-frames, recreate the relevant frame subtree.  The return value
  1.1451 +  // indicates whether this happened.  If this method returns true, *aResult is
  1.1452 +  // the return value of ReframeContainingBlock or RecreateFramesForContent.  If
  1.1453 +  // this method returns false, the value of *aResult is not affected.  aFrame
  1.1454 +  // and aResult must not be null.  aFrame must be the result of a
  1.1455 +  // GetPrimaryFrame() call on a content node (which means its parent is also
  1.1456 +  // not null).
  1.1457 +  bool MaybeRecreateContainerForFrameRemoval(nsIFrame* aFrame,
  1.1458 +                                               nsresult* aResult);
  1.1459 +
  1.1460 +  nsIFrame* CreateContinuingOuterTableFrame(nsIPresShell*    aPresShell,
  1.1461 +                                            nsPresContext*  aPresContext,
  1.1462 +                                            nsIFrame*        aFrame,
  1.1463 +                                            nsIFrame*        aParentFrame,
  1.1464 +                                            nsIContent*      aContent,
  1.1465 +                                            nsStyleContext*  aStyleContext);
  1.1466 +
  1.1467 +  nsIFrame* CreateContinuingTableFrame(nsIPresShell*    aPresShell,
  1.1468 +                                       nsPresContext*  aPresContext,
  1.1469 +                                       nsIFrame*        aFrame,
  1.1470 +                                       nsIFrame*        aParentFrame,
  1.1471 +                                       nsIContent*      aContent,
  1.1472 +                                       nsStyleContext*  aStyleContext);
  1.1473 +
  1.1474 +  //----------------------------------------
  1.1475 +
  1.1476 +  // Methods support creating block frames and their children
  1.1477 +
  1.1478 +  already_AddRefed<nsStyleContext>
  1.1479 +  GetFirstLetterStyle(nsIContent*      aContent,
  1.1480 +                      nsStyleContext*  aStyleContext);
  1.1481 +
  1.1482 +  already_AddRefed<nsStyleContext>
  1.1483 +  GetFirstLineStyle(nsIContent*      aContent,
  1.1484 +                    nsStyleContext*  aStyleContext);
  1.1485 +
  1.1486 +  bool ShouldHaveFirstLetterStyle(nsIContent*      aContent,
  1.1487 +                                    nsStyleContext*  aStyleContext);
  1.1488 +
  1.1489 +  // Check whether a given block has first-letter style.  Make sure to
  1.1490 +  // only pass in blocks!  And don't pass in null either.
  1.1491 +  bool HasFirstLetterStyle(nsIFrame* aBlockFrame);
  1.1492 +
  1.1493 +  bool ShouldHaveFirstLineStyle(nsIContent*      aContent,
  1.1494 +                                  nsStyleContext*  aStyleContext);
  1.1495 +
  1.1496 +  void ShouldHaveSpecialBlockStyle(nsIContent*      aContent,
  1.1497 +                                   nsStyleContext*  aStyleContext,
  1.1498 +                                   bool*          aHaveFirstLetterStyle,
  1.1499 +                                   bool*          aHaveFirstLineStyle);
  1.1500 +
  1.1501 +  // |aContentParentFrame| should be null if it's really the same as
  1.1502 +  // |aParentFrame|.
  1.1503 +  // @param aFrameItems where we want to put the block in case it's in-flow.
  1.1504 +  // @param aNewFrame an in/out parameter. On input it is the block to be
  1.1505 +  // constructed. On output it is reset to the outermost
  1.1506 +  // frame constructed (e.g. if we need to wrap the block in an
  1.1507 +  // nsColumnSetFrame.
  1.1508 +  // @param aParentFrame is the desired parent for the (possibly wrapped)
  1.1509 +  // block
  1.1510 +  // @param aContentParent is the parent the block would have if it
  1.1511 +  // were in-flow
  1.1512 +  // @param aPositionedFrameForAbsPosContainer if non-null, then the new
  1.1513 +  // block should be an abs-pos container and aPositionedFrameForAbsPosContainer
  1.1514 +  // is the frame whose style is making this block an abs-pos container.
  1.1515 +  // @param aPendingBinding the pending binding  from this block's frame
  1.1516 +  // construction item.
  1.1517 +  void ConstructBlock(nsFrameConstructorState& aState,
  1.1518 +                      const nsStyleDisplay*    aDisplay,
  1.1519 +                      nsIContent*              aContent,
  1.1520 +                      nsIFrame*                aParentFrame,
  1.1521 +                      nsIFrame*                aContentParentFrame,
  1.1522 +                      nsStyleContext*          aStyleContext,
  1.1523 +                      nsIFrame**               aNewFrame,
  1.1524 +                      nsFrameItems&            aFrameItems,
  1.1525 +                      nsIFrame*                aPositionedFrameForAbsPosContainer,
  1.1526 +                      PendingBinding*          aPendingBinding);
  1.1527 +
  1.1528 +  nsIFrame* ConstructInline(nsFrameConstructorState& aState,
  1.1529 +                            FrameConstructionItem&   aItem,
  1.1530 +                            nsIFrame*                aParentFrame,
  1.1531 +                            const nsStyleDisplay*    aDisplay,
  1.1532 +                            nsFrameItems&            aFrameItems);
  1.1533 +
  1.1534 +  /**
  1.1535 +   * Create any additional {ib} siblings needed to contain aChildItems and put
  1.1536 +   * them in aSiblings.
  1.1537 +   *
  1.1538 +   * @param aState the frame constructor state
  1.1539 +   * @param aInitialInline is an already-existing inline frame that will be
  1.1540 +   *                       part of this {ib} split and come before everything
  1.1541 +   *                       in aSiblings.
  1.1542 +   * @param aIsPositioned true if aInitialInline is positioned.
  1.1543 +   * @param aChildItems is a child list starting with a block; this method
  1.1544 +   *                    assumes that the inline has already taken all the
  1.1545 +   *                    children it wants.  When the method returns aChildItems
  1.1546 +   *                    will be empty.
  1.1547 +   * @param aSiblings the nsFrameItems to put the newly-created siblings into.
  1.1548 +   *
  1.1549 +   * This method is responsible for making any SetFrameIsIBSplit calls that are
  1.1550 +   * needed.
  1.1551 +   */
  1.1552 +  void CreateIBSiblings(nsFrameConstructorState& aState,
  1.1553 +                        nsIFrame* aInitialInline,
  1.1554 +                        bool aIsPositioned,
  1.1555 +                        nsFrameItems& aChildItems,
  1.1556 +                        nsFrameItems& aSiblings);
  1.1557 +
  1.1558 +  /**
  1.1559 +   * For an inline aParentItem, construct its list of child
  1.1560 +   * FrameConstructionItems and set its mIsAllInline flag appropriately.
  1.1561 +   */
  1.1562 +  void BuildInlineChildItems(nsFrameConstructorState& aState,
  1.1563 +                             FrameConstructionItem& aParentItem,
  1.1564 +                             bool aItemIsWithinSVGText,
  1.1565 +                             bool aItemAllowsTextPathChild);
  1.1566 +
  1.1567 +  // Determine whether we need to wipe out what we just did and start over
  1.1568 +  // because we're doing something like adding block kids to an inline frame
  1.1569 +  // (and therefore need an {ib} split).  aPrevSibling must be correct, even in
  1.1570 +  // aIsAppend cases.  Passing aIsAppend false even when an append is happening
  1.1571 +  // is ok in terms of correctness, but can lead to unnecessary reframing.  If
  1.1572 +  // aIsAppend is true, then the caller MUST call
  1.1573 +  // nsCSSFrameConstructor::AppendFrames (as opposed to
  1.1574 +  // nsFrameManager::InsertFrames directly) to add the new frames.
  1.1575 +  // @return true if we reconstructed the containing block, false
  1.1576 +  // otherwise
  1.1577 +  bool WipeContainingBlock(nsFrameConstructorState& aState,
  1.1578 +                             nsIFrame*                aContainingBlock,
  1.1579 +                             nsIFrame*                aFrame,
  1.1580 +                             FrameConstructionItemList& aItems,
  1.1581 +                             bool                     aIsAppend,
  1.1582 +                             nsIFrame*                aPrevSibling);
  1.1583 +
  1.1584 +  nsresult ReframeContainingBlock(nsIFrame* aFrame);
  1.1585 +
  1.1586 +  //----------------------------------------
  1.1587 +
  1.1588 +  // Methods support :first-letter style
  1.1589 +
  1.1590 +  void CreateFloatingLetterFrame(nsFrameConstructorState& aState,
  1.1591 +                                 nsIFrame*                aBlockFrame,
  1.1592 +                                 nsIContent*              aTextContent,
  1.1593 +                                 nsIFrame*                aTextFrame,
  1.1594 +                                 nsIContent*              aBlockContent,
  1.1595 +                                 nsIFrame*                aParentFrame,
  1.1596 +                                 nsStyleContext*          aStyleContext,
  1.1597 +                                 nsFrameItems&            aResult);
  1.1598 +
  1.1599 +  void CreateLetterFrame(nsIFrame*                aBlockFrame,
  1.1600 +                         nsIFrame*                aBlockContinuation,
  1.1601 +                         nsIContent*              aTextContent,
  1.1602 +                         nsIFrame*                aParentFrame,
  1.1603 +                         nsFrameItems&            aResult);
  1.1604 +
  1.1605 +  void WrapFramesInFirstLetterFrame(nsIContent*   aBlockContent,
  1.1606 +                                    nsIFrame*     aBlockFrame,
  1.1607 +                                    nsFrameItems& aBlockFrames);
  1.1608 +
  1.1609 +  /**
  1.1610 +   * Looks in the block aBlockFrame for a text frame that contains the
  1.1611 +   * first-letter of the block and creates the necessary first-letter frames
  1.1612 +   * and returns them in aLetterFrames.
  1.1613 +   *
  1.1614 +   * @param aBlockFrame the (first-continuation of) the block we are creating a
  1.1615 +   *                    first-letter frame for
  1.1616 +   * @param aBlockContinuation the current continuation of the block that we
  1.1617 +   *                           are looking in for a textframe with suitable
  1.1618 +   *                           contents for first-letter
  1.1619 +   * @param aParentFrame the current frame whose children we are looking at for
  1.1620 +   *                     a suitable first-letter textframe
  1.1621 +   * @param aParentFrameList the first child of aParentFrame
  1.1622 +   * @param aModifiedParent returns the parent of the textframe that contains
  1.1623 +   *                        the first-letter
  1.1624 +   * @param aTextFrame returns the textframe that had the first-letter
  1.1625 +   * @param aPrevFrame returns the previous sibling of aTextFrame
  1.1626 +   * @param aLetterFrames returns the frames that were created
  1.1627 +   * @param aStopLooking returns whether we should stop looking for a
  1.1628 +   *                     first-letter either because it was found or won't be
  1.1629 +   *                     found
  1.1630 +   */
  1.1631 +  void WrapFramesInFirstLetterFrame(nsIFrame*     aBlockFrame,
  1.1632 +                                    nsIFrame*     aBlockContinuation,
  1.1633 +                                    nsIFrame*     aParentFrame,
  1.1634 +                                    nsIFrame*     aParentFrameList,
  1.1635 +                                    nsIFrame**    aModifiedParent,
  1.1636 +                                    nsIFrame**    aTextFrame,
  1.1637 +                                    nsIFrame**    aPrevFrame,
  1.1638 +                                    nsFrameItems& aLetterFrames,
  1.1639 +                                    bool*       aStopLooking);
  1.1640 +
  1.1641 +  void RecoverLetterFrames(nsIFrame* aBlockFrame);
  1.1642 +
  1.1643 +  //
  1.1644 +  nsresult RemoveLetterFrames(nsPresContext*  aPresContext,
  1.1645 +                              nsIPresShell*    aPresShell,
  1.1646 +                              nsIFrame*        aBlockFrame);
  1.1647 +
  1.1648 +  // Recursive helper for RemoveLetterFrames
  1.1649 +  nsresult RemoveFirstLetterFrames(nsPresContext*  aPresContext,
  1.1650 +                                   nsIPresShell*    aPresShell,
  1.1651 +                                   nsIFrame*        aFrame,
  1.1652 +                                   nsIFrame*        aBlockFrame,
  1.1653 +                                   bool*          aStopLooking);
  1.1654 +
  1.1655 +  // Special remove method for those pesky floating first-letter frames
  1.1656 +  nsresult RemoveFloatingFirstLetterFrames(nsPresContext*  aPresContext,
  1.1657 +                                           nsIPresShell*    aPresShell,
  1.1658 +                                           nsIFrame*        aBlockFrame,
  1.1659 +                                           bool*          aStopLooking);
  1.1660 +
  1.1661 +  // Capture state for the frame tree rooted at the frame associated with the
  1.1662 +  // content object, aContent
  1.1663 +  void CaptureStateForFramesOf(nsIContent* aContent,
  1.1664 +                               nsILayoutHistoryState* aHistoryState);
  1.1665 +
  1.1666 +  //----------------------------------------
  1.1667 +
  1.1668 +  // Methods support :first-line style
  1.1669 +
  1.1670 +  // This method chops the initial inline-outside frames out of aFrameItems.
  1.1671 +  // If aLineFrame is non-null, it appends them to that frame.  Otherwise, it
  1.1672 +  // creates a new line frame, sets the inline frames as its initial child
  1.1673 +  // list, and inserts that line frame at the front of what's left of
  1.1674 +  // aFrameItems.  In both cases, the kids are reparented to the line frame.
  1.1675 +  // After this call, aFrameItems holds the frames that need to become kids of
  1.1676 +  // the block (possibly including line frames).
  1.1677 +  void WrapFramesInFirstLineFrame(nsFrameConstructorState& aState,
  1.1678 +                                  nsIContent*              aBlockContent,
  1.1679 +                                  nsIFrame*                aBlockFrame,
  1.1680 +                                  nsIFrame*                aLineFrame,
  1.1681 +                                  nsFrameItems&            aFrameItems);
  1.1682 +
  1.1683 +  // Handle the case when a block with first-line style is appended to (by
  1.1684 +  // possibly calling WrapFramesInFirstLineFrame as needed).
  1.1685 +  void AppendFirstLineFrames(nsFrameConstructorState& aState,
  1.1686 +                             nsIContent*              aContent,
  1.1687 +                             nsIFrame*                aBlockFrame,
  1.1688 +                             nsFrameItems&            aFrameItems);
  1.1689 +
  1.1690 +  nsresult InsertFirstLineFrames(nsFrameConstructorState& aState,
  1.1691 +                                 nsIContent*              aContent,
  1.1692 +                                 nsIFrame*                aBlockFrame,
  1.1693 +                                 nsIFrame**               aParentFrame,
  1.1694 +                                 nsIFrame*                aPrevSibling,
  1.1695 +                                 nsFrameItems&            aFrameItems);
  1.1696 +
  1.1697 +  // Find the right frame to use for aContent when looking for sibling
  1.1698 +  // frames for aTargetContent.  If aPrevSibling is true, this
  1.1699 +  // will look for last continuations, etc, as necessary.  This calls
  1.1700 +  // IsValidSibling as needed; if that returns false it returns null.
  1.1701 +  //
  1.1702 +  // @param aTargetContentDisplay the CSS display enum for aTargetContent if
  1.1703 +  // already known, UNSET_DISPLAY otherwise. It will be filled in if needed.
  1.1704 +  nsIFrame* FindFrameForContentSibling(nsIContent* aContent,
  1.1705 +                                       nsIContent* aTargetContent,
  1.1706 +                                       uint8_t& aTargetContentDisplay,
  1.1707 +                                       bool aPrevSibling);
  1.1708 +
  1.1709 +  // Find the ``rightmost'' frame for the content immediately preceding the one
  1.1710 +  // aIter points to, following continuations if necessary.  aIter is passed by
  1.1711 +  // value on purpose, so as not to modify the caller's iterator.
  1.1712 +  nsIFrame* FindPreviousSibling(mozilla::dom::FlattenedChildIterator aIter,
  1.1713 +                                uint8_t& aTargetContentDisplay);
  1.1714 +
  1.1715 +  // Find the frame for the content node immediately following the one aIter
  1.1716 +  // points to, following continuations if necessary.  aIter is passed by value
  1.1717 +  // on purpose, so as not to modify the caller's iterator.
  1.1718 +  nsIFrame* FindNextSibling(mozilla::dom::FlattenedChildIterator aIter,
  1.1719 +                            uint8_t& aTargetContentDisplay);
  1.1720 +
  1.1721 +  // Find the right previous sibling for an insertion.  This also updates the
  1.1722 +  // parent frame to point to the correct continuation of the parent frame to
  1.1723 +  // use, and returns whether this insertion is to be treated as an append.
  1.1724 +  // aChild is the child being inserted.
  1.1725 +  // aIsRangeInsertSafe returns whether it is safe to do a range insert with
  1.1726 +  // aChild being the first child in the range. It is the callers'
  1.1727 +  // responsibility to check whether a range insert is safe with regards to
  1.1728 +  // fieldsets.
  1.1729 +  // The skip parameters are used to ignore a range of children when looking
  1.1730 +  // for a sibling. All nodes starting from aStartSkipChild and up to but not
  1.1731 +  // including aEndSkipChild will be skipped over when looking for sibling
  1.1732 +  // frames. Skipping a range can deal with XBL but not when there are multiple
  1.1733 +  // insertion points.
  1.1734 +  nsIFrame* GetInsertionPrevSibling(nsIFrame*& aParentFrame, /* inout */
  1.1735 +                                    nsIContent* aContainer,
  1.1736 +                                    nsIContent* aChild,
  1.1737 +                                    bool* aIsAppend,
  1.1738 +                                    bool* aIsRangeInsertSafe,
  1.1739 +                                    nsIContent* aStartSkipChild = nullptr,
  1.1740 +                                    nsIContent *aEndSkipChild = nullptr);
  1.1741 +
  1.1742 +  // see if aContent and aSibling are legitimate siblings due to restrictions
  1.1743 +  // imposed by table columns
  1.1744 +  // XXXbz this code is generally wrong, since the frame for aContent
  1.1745 +  // may be constructed based on tag, not based on aDisplay!
  1.1746 +  bool IsValidSibling(nsIFrame*              aSibling,
  1.1747 +                        nsIContent*            aContent,
  1.1748 +                        uint8_t&               aDisplay);
  1.1749 +
  1.1750 +  void QuotesDirty() {
  1.1751 +    NS_PRECONDITION(mUpdateCount != 0, "Instant quote updates are bad news");
  1.1752 +    mQuotesDirty = true;
  1.1753 +    mDocument->SetNeedLayoutFlush();
  1.1754 +  }
  1.1755 +
  1.1756 +  void CountersDirty() {
  1.1757 +    NS_PRECONDITION(mUpdateCount != 0, "Instant counter updates are bad news");
  1.1758 +    mCountersDirty = true;
  1.1759 +    mDocument->SetNeedLayoutFlush();
  1.1760 +  }
  1.1761 +
  1.1762 +  /**
  1.1763 +   * Add the pair (aContent, aStyleContext) to the undisplayed items
  1.1764 +   * in aList as needed.  This method enforces the invariant that all
  1.1765 +   * style contexts in the undisplayed content map must be non-pseudo
  1.1766 +   * contexts and also handles unbinding undisplayed generated content
  1.1767 +   * as needed.
  1.1768 +   */
  1.1769 +  static void SetAsUndisplayedContent(FrameConstructionItemList& aList,
  1.1770 +                                      nsIContent* aContent,
  1.1771 +                                      nsStyleContext* aStyleContext,
  1.1772 +                                      bool aIsGeneratedContent);
  1.1773 +
  1.1774 +public:
  1.1775 +
  1.1776 +  friend class nsFrameConstructorState;
  1.1777 +
  1.1778 +private:
  1.1779 +
  1.1780 +  nsIDocument*        mDocument;  // Weak ref
  1.1781 +
  1.1782 +  // See the comment at the start of ConstructRootFrame for more details
  1.1783 +  // about the following frames.
  1.1784 +
  1.1785 +  // This is just the outermost frame for the root element.
  1.1786 +  nsIFrame*           mRootElementFrame;
  1.1787 +  // This is the frame for the root element that has no pseudo-element style.
  1.1788 +  nsIFrame*           mRootElementStyleFrame;
  1.1789 +  // This is the containing block for fixed-pos frames --- the
  1.1790 +  // viewport or page frame
  1.1791 +  nsIFrame*           mFixedContainingBlock;
  1.1792 +  // This is the containing block that contains the root element ---
  1.1793 +  // the real "initial containing block" according to CSS 2.1.
  1.1794 +  nsIFrame*           mDocElementContainingBlock;
  1.1795 +  nsIFrame*           mGfxScrollFrame;
  1.1796 +  nsIFrame*           mPageSequenceFrame;
  1.1797 +  nsQuoteList         mQuoteList;
  1.1798 +  nsCounterManager    mCounterManager;
  1.1799 +  // Current ProcessChildren depth.
  1.1800 +  uint16_t            mCurrentDepth;
  1.1801 +  uint16_t            mUpdateCount;
  1.1802 +  bool                mQuotesDirty : 1;
  1.1803 +  bool                mCountersDirty : 1;
  1.1804 +  bool                mIsDestroyingFrameTree : 1;
  1.1805 +  // This is true if mDocElementContainingBlock supports absolute positioning
  1.1806 +  bool                mHasRootAbsPosContainingBlock : 1;
  1.1807 +  bool                mAlwaysCreateFramesForIgnorableWhitespace : 1;
  1.1808 +
  1.1809 +  nsCOMPtr<nsILayoutHistoryState> mTempFrameTreeState;
  1.1810 +};
  1.1811 +
  1.1812 +#endif /* nsCSSFrameConstructor_h___ */

mercurial