LCOV - code coverage report
Current view: top level - layout/generic - nsIFrame.h (source / functions) Hit Total Coverage
Test: output.info Lines: 6 62 9.7 %
Date: 2018-08-07 16:42:27 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : /* interface for all rendering objects */
       8             : 
       9             : #ifndef nsIFrame_h___
      10             : #define nsIFrame_h___
      11             : 
      12             : #ifndef MOZILLA_INTERNAL_API
      13             : #error This header/class should only be used within Mozilla code. It should not be used by extensions.
      14             : #endif
      15             : 
      16             : #define MAX_REFLOW_DEPTH 200
      17             : 
      18             : /* nsIFrame is in the process of being deCOMtaminated, i.e., this file is eventually
      19             :    going to be eliminated, and all callers will use nsFrame instead.  At the moment
      20             :    we're midway through this process, so you will see inlined functions and member
      21             :    variables in this file.  -dwh */
      22             : 
      23             : #include <algorithm>
      24             : #include <stdio.h>
      25             : 
      26             : #include "CaretAssociationHint.h"
      27             : #include "FrameProperties.h"
      28             : #include "LayoutConstants.h"
      29             : #include "mozilla/layout/FrameChildList.h"
      30             : #include "mozilla/Maybe.h"
      31             : #include "mozilla/SmallPointerArray.h"
      32             : #include "mozilla/WritingModes.h"
      33             : #include "nsDirection.h"
      34             : #include "nsFrameList.h"
      35             : #include "nsFrameState.h"
      36             : #include "mozilla/ReflowOutput.h"
      37             : #include "nsITheme.h"
      38             : #include "nsLayoutUtils.h"
      39             : #include "nsQueryFrame.h"
      40             : #include "nsString.h"
      41             : #include "mozilla/ComputedStyle.h"
      42             : #include "nsStyleStruct.h"
      43             : #include "Visibility.h"
      44             : #include "nsChangeHint.h"
      45             : #include "mozilla/ComputedStyleInlines.h"
      46             : #include "mozilla/gfx/CompositorHitTestInfo.h"
      47             : #include "mozilla/gfx/MatrixFwd.h"
      48             : #include "nsDisplayItemTypes.h"
      49             : 
      50             : #ifdef ACCESSIBILITY
      51             : #include "mozilla/a11y/AccTypes.h"
      52             : #endif
      53             : 
      54             : /**
      55             :  * New rules of reflow:
      56             :  * 1. you get a WillReflow() followed by a Reflow() followed by a DidReflow() in order
      57             :  *    (no separate pass over the tree)
      58             :  * 2. it's the parent frame's responsibility to size/position the child's view (not
      59             :  *    the child frame's responsibility as it is today) during reflow (and before
      60             :  *    sending the DidReflow() notification)
      61             :  * 3. positioning of child frames (and their views) is done on the way down the tree,
      62             :  *    and sizing of child frames (and their views) on the way back up
      63             :  * 4. if you move a frame (outside of the reflow process, or after reflowing it),
      64             :  *    then you must make sure that its view (or its child frame's views) are re-positioned
      65             :  *    as well. It's reasonable to not position the view until after all reflowing the
      66             :  *    entire line, for example, but the frame should still be positioned and sized (and
      67             :  *    the view sized) during the reflow (i.e., before sending the DidReflow() notification)
      68             :  * 5. the view system handles moving of widgets, i.e., it's not our problem
      69             :  */
      70             : 
      71             : class nsAtom;
      72             : class nsPresContext;
      73             : class nsIPresShell;
      74             : class nsView;
      75             : class nsIWidget;
      76             : class nsISelectionController;
      77             : class nsBoxLayoutState;
      78             : class nsBoxLayout;
      79             : class nsILineIterator;
      80             : class nsDisplayItem;
      81             : class nsDisplayListBuilder;
      82             : class nsDisplayListSet;
      83             : class nsDisplayList;
      84             : class gfxSkipChars;
      85             : class gfxSkipCharsIterator;
      86             : class gfxContext;
      87             : class nsLineList_iterator;
      88             : class nsAbsoluteContainingBlock;
      89             : class nsIContent;
      90             : class nsContainerFrame;
      91             : class nsPlaceholderFrame;
      92             : class nsStyleChangeList;
      93             : class nsWindowSizes;
      94             : 
      95             : struct nsPeekOffsetStruct;
      96             : struct nsPoint;
      97             : struct nsRect;
      98             : struct nsSize;
      99             : struct nsMargin;
     100             : struct CharacterDataChangeInfo;
     101             : 
     102             : namespace mozilla {
     103             : 
     104             : enum class CSSPseudoElementType : uint8_t;
     105             : class EventStates;
     106             : struct ReflowInput;
     107             : class ReflowOutput;
     108             : class ServoRestyleState;
     109             : class DisplayItemData;
     110             : class EffectSet;
     111             : 
     112             : namespace layers {
     113             : class Layer;
     114             : class LayerManager;
     115             : } // namespace layers
     116             : 
     117             : namespace dom {
     118             : class Selection;
     119             : } // namespace dom
     120             : 
     121             : } // namespace mozilla
     122             : 
     123             : /**
     124             :  * Indication of how the frame can be split. This is used when doing runaround
     125             :  * of floats, and when pulling up child frames from a next-in-flow.
     126             :  *
     127             :  * The choices are splittable, not splittable at all, and splittable in
     128             :  * a non-rectangular fashion. This last type only applies to block-level
     129             :  * elements, and indicates whether splitting can be used when doing runaround.
     130             :  * If you can split across page boundaries, but you expect each continuing
     131             :  * frame to be the same width then return frSplittable and not
     132             :  * frSplittableNonRectangular.
     133             :  *
     134             :  * @see #GetSplittableType()
     135             :  */
     136             : typedef uint32_t nsSplittableType;
     137             : 
     138             : #define NS_FRAME_NOT_SPLITTABLE             0   // Note: not a bit!
     139             : #define NS_FRAME_SPLITTABLE                 0x1
     140             : #define NS_FRAME_SPLITTABLE_NON_RECTANGULAR 0x3
     141             : 
     142             : #define NS_FRAME_IS_SPLITTABLE(type)\
     143             :   (0 != ((type) & NS_FRAME_SPLITTABLE))
     144             : 
     145             : #define NS_FRAME_IS_NOT_SPLITTABLE(type)\
     146             :   (0 == ((type) & NS_FRAME_SPLITTABLE))
     147             : 
     148             : //----------------------------------------------------------------------
     149             : 
     150             : #define NS_SUBTREE_DIRTY(_frame)  \
     151             :   (((_frame)->GetStateBits() &      \
     152             :     (NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN)) != 0)
     153             : 
     154             : // 1 million CSS pixels less than our max app unit measure.
     155             : // For reflowing with an "infinite" available inline space per [css-sizing].
     156             : // (reflowing with an NS_UNCONSTRAINEDSIZE available inline size isn't allowed
     157             : //  and leads to assertions)
     158             : #define INFINITE_ISIZE_COORD nscoord(NS_MAXSIZE - (1000000*60))
     159             : 
     160             : //----------------------------------------------------------------------
     161             : 
     162             : namespace mozilla {
     163             : 
     164             : enum class LayoutFrameType : uint8_t {
     165             : #define FRAME_TYPE(ty_) ty_,
     166             : #include "mozilla/FrameTypeList.h"
     167             : #undef FRAME_TYPE
     168             : };
     169             : 
     170             : } // namespace mozilla
     171             : 
     172             : enum nsSelectionAmount {
     173             :   eSelectCharacter = 0, // a single Unicode character;
     174             :                         // do not use this (prefer Cluster) unless you
     175             :                         // are really sure it's what you want
     176             :   eSelectCluster   = 1, // a grapheme cluster: this is usually the right
     177             :                         // choice for movement or selection by "character"
     178             :                         // as perceived by the user
     179             :   eSelectWord      = 2,
     180             :   eSelectWordNoSpace = 3, // select a "word" without selecting the following
     181             :                           // space, no matter what the default platform
     182             :                           // behavior is
     183             :   eSelectLine      = 4, // previous drawn line in flow.
     184             :   // NOTE that selection code depends on the ordering of the above values,
     185             :   // allowing simple <= tests to check categories of caret movement.
     186             :   // Don't rearrange without checking the usage in nsSelection.cpp!
     187             : 
     188             :   eSelectBeginLine = 5,
     189             :   eSelectEndLine   = 6,
     190             :   eSelectNoAmount  = 7, // just bounce back current offset.
     191             :   eSelectParagraph = 8  // select a "paragraph"
     192             : };
     193             : 
     194             : enum nsSpread {
     195             :   eSpreadNone   = 0,
     196             :   eSpreadAcross = 1,
     197             :   eSpreadDown   = 2
     198             : };
     199             : 
     200             : // Carried out margin flags
     201             : #define NS_CARRIED_TOP_MARGIN_IS_AUTO    0x1
     202             : #define NS_CARRIED_BOTTOM_MARGIN_IS_AUTO 0x2
     203             : 
     204             : //----------------------------------------------------------------------
     205             : // Reflow status returned by the Reflow() methods.
     206             : class nsReflowStatus final {
     207             :   using StyleClear = mozilla::StyleClear;
     208             : 
     209             : public:
     210             :   nsReflowStatus()
     211             :     : mBreakType(StyleClear::None)
     212             :     , mInlineBreak(InlineBreak::None)
     213             :     , mCompletion(Completion::FullyComplete)
     214             :     , mNextInFlowNeedsReflow(false)
     215             :     , mTruncated(false)
     216             :     , mFirstLetterComplete(false)
     217             :   {}
     218             : 
     219             :   // Reset all the member variables.
     220             :   void Reset() {
     221             :     mBreakType = StyleClear::None;
     222             :     mInlineBreak = InlineBreak::None;
     223             :     mCompletion = Completion::FullyComplete;
     224             :     mNextInFlowNeedsReflow = false;
     225             :     mTruncated = false;
     226             :     mFirstLetterComplete = false;
     227             :   }
     228             : 
     229             :   // Return true if all member variables have their default values.
     230             :   bool IsEmpty() const {
     231             :     return (IsFullyComplete() &&
     232             :             !IsInlineBreak() &&
     233             :             !mNextInFlowNeedsReflow &&
     234             :             !mTruncated &&
     235             :             !mFirstLetterComplete);
     236             :   }
     237             : 
     238             :   // There are three possible completion statuses, represented by
     239             :   // mCompletion.
     240             :   //
     241             :   // Incomplete means the frame does *not* map all its content, and the
     242             :   // parent frame should create a continuing frame.
     243             :   //
     244             :   // OverflowIncomplete means that the frame has an overflow that is not
     245             :   // complete, but its own box is complete. (This happens when the content
     246             :   // overflows a fixed-height box.) The reflower should place and size the
     247             :   // frame and continue its reflow, but it needs to create an overflow
     248             :   // container as a continuation for this frame. See "Overflow containers"
     249             :   // documentation in nsContainerFrame.h for more information.
     250             :   //
     251             :   // FullyComplete means the frame is neither Incomplete nor
     252             :   // OverflowIncomplete. This is the default state for a nsReflowStatus.
     253             :   //
     254             :   enum class Completion : uint8_t {
     255             :     // The order of the enum values is important, which represents the
     256             :     // precedence when merging.
     257             :     FullyComplete,
     258             :     OverflowIncomplete,
     259             :     Incomplete,
     260             :   };
     261             : 
     262             :   bool IsIncomplete() const { return mCompletion == Completion::Incomplete; }
     263             :   bool IsOverflowIncomplete() const {
     264             :     return mCompletion == Completion::OverflowIncomplete;
     265             :   }
     266             :   bool IsFullyComplete() const {
     267             :     return mCompletion == Completion::FullyComplete;
     268             :   }
     269             :   // Just for convenience; not a distinct state.
     270             :   bool IsComplete() const { return !IsIncomplete(); }
     271             : 
     272             :   void SetIncomplete() {
     273             :     mCompletion = Completion::Incomplete;
     274             :   }
     275             :   void SetOverflowIncomplete() {
     276             :     mCompletion = Completion::OverflowIncomplete;
     277             :   }
     278             : 
     279             :   // mNextInFlowNeedsReflow bit flag means that the next-in-flow is dirty,
     280             :   // and also needs to be reflowed. This status only makes sense for a frame
     281             :   // that is not complete, i.e. you wouldn't set mNextInFlowNeedsReflow when
     282             :   // IsComplete() is true.
     283             :   bool NextInFlowNeedsReflow() const { return mNextInFlowNeedsReflow; }
     284             :   void SetNextInFlowNeedsReflow() { mNextInFlowNeedsReflow = true; }
     285             : 
     286             :   // mTruncated bit flag means that the part of the frame before the first
     287             :   // possible break point was unable to fit in the available space.
     288             :   // Therefore, the entire frame should be moved to the next continuation of
     289             :   // the parent frame. A frame that begins at the top of the page must never
     290             :   // be truncated. Doing so would likely cause an infinite loop.
     291             :   bool IsTruncated() const { return mTruncated; }
     292             :   void UpdateTruncated(const mozilla::ReflowInput& aReflowInput,
     293             :                        const mozilla::ReflowOutput& aMetrics);
     294             : 
     295             :   // Merge the frame completion status bits from aStatus into this.
     296             :   void MergeCompletionStatusFrom(const nsReflowStatus& aStatus)
     297             :   {
     298             :     if (mCompletion < aStatus.mCompletion) {
     299             :       mCompletion = aStatus.mCompletion;
     300             :     }
     301             : 
     302             :     // These asserts ensure that the mCompletion merging works as we expect.
     303             :     // (Incomplete beats OverflowIncomplete, which beats FullyComplete.)
     304             :     static_assert(Completion::Incomplete > Completion::OverflowIncomplete &&
     305             :                   Completion::OverflowIncomplete > Completion::FullyComplete,
     306             :                   "mCompletion merging won't work without this!");
     307             : 
     308             :     mNextInFlowNeedsReflow |= aStatus.mNextInFlowNeedsReflow;
     309             :     mTruncated |= aStatus.mTruncated;
     310             :   }
     311             : 
     312             :   // There are three possible inline-break statuses, represented by
     313             :   // mInlineBreak.
     314             :   //
     315             :   // "None" means no break is requested.
     316             :   // "Before" means the break should occur before the frame.
     317             :   // "After" means the break should occur after the frame.
     318             :   // (Here, "the frame" is the frame whose reflow results are being reported by
     319             :   // this nsReflowStatus.)
     320             :   //
     321             :   enum class InlineBreak : uint8_t {
     322             :     None,
     323             :     Before,
     324             :     After,
     325             :   };
     326             : 
     327             :   bool IsInlineBreak() const { return mInlineBreak != InlineBreak::None; }
     328             :   bool IsInlineBreakBefore() const {
     329             :     return mInlineBreak == InlineBreak::Before;
     330             :   }
     331             :   bool IsInlineBreakAfter() const {
     332             :     return mInlineBreak == InlineBreak::After;
     333             :   }
     334             :   StyleClear BreakType() const { return mBreakType; }
     335             : 
     336             :   // Set the inline line-break-before status, and reset other bit flags. The
     337             :   // break type is StyleClear::Line. Note that other frame completion status
     338             :   // isn't expected to matter after calling this method.
     339             :   void SetInlineLineBreakBeforeAndReset() {
     340             :     Reset();
     341             :     mBreakType = StyleClear::Line;
     342             :     mInlineBreak = InlineBreak::Before;
     343             :   }
     344             : 
     345             :   // Set the inline line-break-after status. The break type can be changed
     346             :   // via the optional aBreakType param.
     347             :   void SetInlineLineBreakAfter(StyleClear aBreakType = StyleClear::Line) {
     348             :     MOZ_ASSERT(aBreakType != StyleClear::None,
     349             :                "Break-after with StyleClear::None is meaningless!");
     350             :     mBreakType = aBreakType;
     351             :     mInlineBreak = InlineBreak::After;
     352             :   }
     353             : 
     354             :   // mFirstLetterComplete bit flag means the break was induced by
     355             :   // completion of a first-letter.
     356             :   bool FirstLetterComplete() const { return mFirstLetterComplete; }
     357             :   void SetFirstLetterComplete() { mFirstLetterComplete = true; }
     358             : 
     359             : #ifdef DEBUG
     360             :   nsCString ToString() const;
     361             : #endif
     362             : 
     363             : private:
     364             :   StyleClear mBreakType;
     365             :   InlineBreak mInlineBreak;
     366             :   Completion mCompletion;
     367             :   bool mNextInFlowNeedsReflow : 1;
     368             :   bool mTruncated : 1;
     369             :   bool mFirstLetterComplete : 1;
     370             : };
     371             : 
     372             : #define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \
     373             :   aStatus.UpdateTruncated(aReflowInput, aMetrics);
     374             : 
     375             : #ifdef DEBUG
     376             : // Convert nsReflowStatus to a human-readable string.
     377             : std::ostream&
     378             : operator<<(std::ostream& aStream, const nsReflowStatus& aStatus);
     379             : #endif
     380             : 
     381             : //----------------------------------------------------------------------
     382             : 
     383             : /**
     384             :  * When there is no scrollable overflow rect, the visual overflow rect
     385             :  * may be stored as four 1-byte deltas each strictly LESS THAN 0xff, for
     386             :  * the four edges of the rectangle, or the four bytes may be read as a
     387             :  * single 32-bit "overflow-rect type" value including at least one 0xff
     388             :  * byte as an indicator that the value does NOT represent four deltas.
     389             :  * If all four deltas are zero, this means that no overflow rect has
     390             :  * actually been set (this is the initial state of newly-created frames).
     391             :  */
     392             : #define NS_FRAME_OVERFLOW_DELTA_MAX     0xfe // max delta we can store
     393             : 
     394             : #define NS_FRAME_OVERFLOW_NONE    0x00000000 // there are no overflow rects;
     395             :                                              // code relies on this being
     396             :                                              // the all-zero value
     397             : 
     398             : #define NS_FRAME_OVERFLOW_LARGE   0x000000ff // overflow is stored as a
     399             :                                              // separate rect property
     400             : 
     401             : /**
     402             :  * nsBidiLevel is the type of the level values in our Unicode Bidi
     403             :  * implementation.
     404             :  * It holds an embedding level and indicates the visual direction
     405             :  * by its bit 0 (even/odd value).<p>
     406             :  *
     407             :  * <li><code>aParaLevel</code> can be set to the
     408             :  * pseudo-level values <code>NSBIDI_DEFAULT_LTR</code>
     409             :  * and <code>NSBIDI_DEFAULT_RTL</code>.</li></ul>
     410             :  *
     411             :  * @see nsBidi::SetPara
     412             :  *
     413             :  * <p>The related constants are not real, valid level values.
     414             :  * <code>NSBIDI_DEFAULT_XXX</code> can be used to specify
     415             :  * a default for the paragraph level for
     416             :  * when the <code>SetPara</code> function
     417             :  * shall determine it but there is no
     418             :  * strongly typed character in the input.<p>
     419             :  *
     420             :  * Note that the value for <code>NSBIDI_DEFAULT_LTR</code> is even
     421             :  * and the one for <code>NSBIDI_DEFAULT_RTL</code> is odd,
     422             :  * just like with normal LTR and RTL level values -
     423             :  * these special values are designed that way. Also, the implementation
     424             :  * assumes that NSBIDI_MAX_EXPLICIT_LEVEL is odd.
     425             :  *
     426             :  * @see NSBIDI_DEFAULT_LTR
     427             :  * @see NSBIDI_DEFAULT_RTL
     428             :  * @see NSBIDI_LEVEL_OVERRIDE
     429             :  * @see NSBIDI_MAX_EXPLICIT_LEVEL
     430             :  */
     431             : typedef uint8_t nsBidiLevel;
     432             : 
     433             : /** Paragraph level setting.
     434             :  *  If there is no strong character, then set the paragraph level to 0 (left-to-right).
     435             :  */
     436             : #define NSBIDI_DEFAULT_LTR 0xfe
     437             : 
     438             : /** Paragraph level setting.
     439             :  *  If there is no strong character, then set the paragraph level to 1 (right-to-left).
     440             :  */
     441             : #define NSBIDI_DEFAULT_RTL 0xff
     442             : 
     443             : /**
     444             :  * Maximum explicit embedding level.
     445             :  * (The maximum resolved level can be up to <code>NSBIDI_MAX_EXPLICIT_LEVEL+1</code>).
     446             :  *
     447             :  */
     448             : #define NSBIDI_MAX_EXPLICIT_LEVEL 125
     449             : 
     450             : /** Bit flag for level input.
     451             :  *  Overrides directional properties.
     452             :  */
     453             : #define NSBIDI_LEVEL_OVERRIDE 0x80
     454             : 
     455             : /**
     456             :  * <code>nsBidiDirection</code> values indicate the text direction.
     457             :  */
     458             : enum nsBidiDirection {
     459             :   /** All left-to-right text This is a 0 value. */
     460             :   NSBIDI_LTR,
     461             :   /** All right-to-left text This is a 1 value. */
     462             :   NSBIDI_RTL,
     463             :   /** Mixed-directional text. */
     464             :   NSBIDI_MIXED
     465             : };
     466             : 
     467             : namespace mozilla {
     468             : 
     469             : // https://drafts.csswg.org/css-align-3/#baseline-sharing-group
     470             : enum BaselineSharingGroup
     471             : {
     472             :   // NOTE Used as an array index so must be 0 and 1.
     473             :   eFirst = 0,
     474             :   eLast = 1,
     475             : };
     476             : 
     477             : // Loosely: https://drafts.csswg.org/css-align-3/#shared-alignment-context
     478             : enum class AlignmentContext
     479             : {
     480             :   eInline,
     481             :   eTable,
     482             :   eFlexbox,
     483             :   eGrid,
     484             : };
     485             : 
     486             : /*
     487             :  * For replaced elements only. Gets the intrinsic dimensions of this element.
     488             :  * The dimensions may only be one of the following two types:
     489             :  *
     490             :  *   eStyleUnit_Coord   - a length in app units
     491             :  *   eStyleUnit_None    - the element has no intrinsic size in this dimension
     492             :  */
     493           0 : struct IntrinsicSize {
     494             :   nsStyleCoord width, height;
     495             : 
     496             :   IntrinsicSize()
     497             :     : width(eStyleUnit_None), height(eStyleUnit_None)
     498             :   {}
     499             :   IntrinsicSize(const IntrinsicSize& rhs)
     500             :     : width(rhs.width), height(rhs.height)
     501             :   {}
     502             :   IntrinsicSize& operator=(const IntrinsicSize& rhs) {
     503             :     width = rhs.width; height = rhs.height; return *this;
     504             :   }
     505             :   bool operator==(const IntrinsicSize& rhs) {
     506             :     return width == rhs.width && height == rhs.height;
     507             :   }
     508             :   bool operator!=(const IntrinsicSize& rhs) {
     509             :     return !(*this == rhs);
     510             :   }
     511             : };
     512             : 
     513             : // Pseudo bidi embedding level indicating nonexistence.
     514             : static const nsBidiLevel kBidiLevelNone = 0xff;
     515             : 
     516             : struct FrameBidiData
     517             : {
     518             :   nsBidiLevel baseLevel;
     519             :   nsBidiLevel embeddingLevel;
     520             :   // The embedding level of virtual bidi formatting character before
     521             :   // this frame if any. kBidiLevelNone is used to indicate nonexistence
     522             :   // or unnecessity of such virtual character.
     523             :   nsBidiLevel precedingControl;
     524             : };
     525             : 
     526             : } // namespace mozilla
     527             : 
     528             : /// Generic destructor for frame properties. Calls delete.
     529             : template<typename T>
     530           0 : static void DeleteValue(T* aPropertyValue)
     531             : {
     532           0 :   delete aPropertyValue;
     533           0 : }
     534             : 
     535             : /// Generic destructor for frame properties. Calls Release().
     536             : template<typename T>
     537             : static void ReleaseValue(T* aPropertyValue)
     538             : {
     539             :   aPropertyValue->Release();
     540             : }
     541             : 
     542             : //----------------------------------------------------------------------
     543             : 
     544             : /**
     545             :  * A frame in the layout model. This interface is supported by all frame
     546             :  * objects.
     547             :  *
     548             :  * Frames can have multiple child lists: the default child list
     549             :  * (referred to as the <i>principal</i> child list, and additional named
     550             :  * child lists. There is an ordering of frames within a child list, but
     551             :  * there is no order defined between frames in different child lists of
     552             :  * the same parent frame.
     553             :  *
     554             :  * Frames are NOT reference counted. Use the Destroy() member function
     555             :  * to destroy a frame. The lifetime of the frame hierarchy is bounded by the
     556             :  * lifetime of the presentation shell which owns the frames.
     557             :  *
     558             :  * nsIFrame is a private Gecko interface. If you are not Gecko then you
     559             :  * should not use it. If you're not in layout, then you won't be able to
     560             :  * link to many of the functions defined here. Too bad.
     561             :  *
     562             :  * If you're not in layout but you must call functions in here, at least
     563             :  * restrict yourself to calling virtual methods, which won't hurt you as badly.
     564             :  */
     565             : class nsIFrame : public nsQueryFrame
     566             : {
     567             : public:
     568             :   using AlignmentContext = mozilla::AlignmentContext;
     569             :   using BaselineSharingGroup = mozilla::BaselineSharingGroup;
     570             :   template <typename T> using Maybe = mozilla::Maybe<T>;
     571             :   using Nothing = mozilla::Nothing;
     572             :   using OnNonvisible = mozilla::OnNonvisible;
     573             :   template<typename T=void>
     574             :   using PropertyDescriptor = const mozilla::FramePropertyDescriptor<T>*;
     575             :   using ReflowInput = mozilla::ReflowInput;
     576             :   using ReflowOutput = mozilla::ReflowOutput;
     577             :   using Visibility = mozilla::Visibility;
     578             : 
     579             :   typedef mozilla::ComputedStyle ComputedStyle;
     580             :   typedef mozilla::FrameProperties FrameProperties;
     581             :   typedef mozilla::layers::Layer Layer;
     582             :   typedef mozilla::layers::LayerManager LayerManager;
     583             :   typedef mozilla::layout::FrameChildList ChildList;
     584             :   typedef mozilla::layout::FrameChildListID ChildListID;
     585             :   typedef mozilla::layout::FrameChildListIDs ChildListIDs;
     586             :   typedef mozilla::layout::FrameChildListIterator ChildListIterator;
     587             :   typedef mozilla::layout::FrameChildListArrayIterator ChildListArrayIterator;
     588             :   typedef mozilla::gfx::DrawTarget DrawTarget;
     589             :   typedef mozilla::gfx::Matrix Matrix;
     590             :   typedef mozilla::gfx::Matrix4x4 Matrix4x4;
     591             :   typedef mozilla::gfx::Matrix4x4Flagged Matrix4x4Flagged;
     592             :   typedef mozilla::Sides Sides;
     593             :   typedef mozilla::LogicalSides LogicalSides;
     594             :   typedef mozilla::SmallPointerArray<mozilla::DisplayItemData> DisplayItemDataArray;
     595             :   typedef nsQueryFrame::ClassID ClassID;
     596             : 
     597             :   NS_DECL_QUERYFRAME_TARGET(nsIFrame)
     598             : 
     599             :   explicit nsIFrame(ClassID aID)
     600             :     : mRect()
     601             :     , mContent(nullptr)
     602             :     , mComputedStyle(nullptr)
     603             :     , mParent(nullptr)
     604             :     , mNextSibling(nullptr)
     605             :     , mPrevSibling(nullptr)
     606             :     , mState(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY)
     607             :     , mClass(aID)
     608             :     , mMayHaveRoundedCorners(false)
     609             :     , mHasImageRequest(false)
     610             :     , mHasFirstLetterChild(false)
     611             :     , mParentIsWrapperAnonBox(false)
     612             :     , mIsWrapperBoxNeedingRestyle(false)
     613             :     , mReflowRequestedForCharDataChange(false)
     614             :     , mForceDescendIntoIfVisible(false)
     615             :     , mBuiltDisplayList(false)
     616             :     , mFrameIsModified(false)
     617             :     , mHasOverrideDirtyRegion(false)
     618             :     , mMayHaveWillChangeBudget(false)
     619             :     , mIsPrimaryFrame(false)
     620             :     , mMayHaveTransformAnimation(false)
     621             :     , mMayHaveOpacityAnimation(false)
     622             :     , mAllDescendantsAreInvisible(false)
     623             :   {
     624             :     mozilla::PodZero(&mOverflow);
     625             :   }
     626             : 
     627             :   nsPresContext* PresContext() const {
     628           2 :     return Style()->PresContextForFrame();
     629             :   }
     630             : 
     631           0 :   nsIPresShell* PresShell() const {
     632           0 :     return PresContext()->PresShell();
     633             :   }
     634             : 
     635             :   /**
     636             :    * Called to initialize the frame. This is called immediately after creating
     637             :    * the frame.
     638             :    *
     639             :    * If the frame is a continuing frame, then aPrevInFlow indicates the previous
     640             :    * frame (the frame that was split).
     641             :    *
     642             :    * Each subclass that need a view should override this method and call
     643             :    * CreateView() after calling its base class Init().
     644             :    *
     645             :    * @param   aContent the content object associated with the frame
     646             :    * @param   aParent the parent frame
     647             :    * @param   aPrevInFlow the prev-in-flow frame
     648             :    */
     649             :   virtual void Init(nsIContent*       aContent,
     650             :                     nsContainerFrame* aParent,
     651             :                     nsIFrame*         aPrevInFlow) = 0;
     652             : 
     653             :   using PostDestroyData = mozilla::layout::PostFrameDestroyData;
     654             :   struct MOZ_RAII AutoPostDestroyData
     655             :   {
     656             :     explicit AutoPostDestroyData(nsPresContext* aPresContext)
     657             :       : mPresContext(aPresContext) {}
     658             :     ~AutoPostDestroyData() {
     659             :       for (auto& content : mozilla::Reversed(mData.mAnonymousContent)) {
     660             :         nsIFrame::DestroyAnonymousContent(mPresContext, content.forget());
     661             :       }
     662             :       for (auto& content : mozilla::Reversed(mData.mGeneratedContent)) {
     663             :         content->UnbindFromTree();
     664             :       }
     665             :     }
     666             :     nsPresContext* mPresContext;
     667             :     PostDestroyData mData;
     668             :   };
     669             :   /**
     670             :    * Destroys this frame and each of its child frames (recursively calls
     671             :    * Destroy() for each child). If this frame is a first-continuation, this
     672             :    * also removes the frame from the primary frame map and clears undisplayed
     673             :    * content for its content node.
     674             :    * If the frame is a placeholder, it also ensures the out-of-flow frame's
     675             :    * removal and destruction.
     676             :    */
     677             :   void Destroy() {
     678             :     AutoPostDestroyData data(PresContext());
     679             :     DestroyFrom(this, data.mData);
     680             :     // Note that |this| is deleted at this point.
     681             :   }
     682             : 
     683             :   /** Flags for PeekOffsetCharacter, PeekOffsetNoAmount, PeekOffsetWord return values.
     684             :     */
     685             :   enum FrameSearchResult {
     686             :     // Peek found a appropriate offset within frame.
     687             :     FOUND = 0x00,
     688             :     // try next frame for offset.
     689             :     CONTINUE = 0x1,
     690             :     // offset not found because the frame was empty of text.
     691             :     CONTINUE_EMPTY = 0x2 | CONTINUE,
     692             :     // offset not found because the frame didn't contain any text that could be selected.
     693             :     CONTINUE_UNSELECTABLE = 0x4 | CONTINUE,
     694             :   };
     695             : 
     696             :   /**
     697             :    * Options for PeekOffsetCharacter().
     698             :    */
     699             :   struct MOZ_STACK_CLASS PeekOffsetCharacterOptions
     700             :   {
     701             :     // Whether to restrict result to valid cursor locations (between grapheme
     702             :     // clusters) - if this is included, maintains "normal" behavior, otherwise,
     703             :     // used for selection by "code unit" (instead of "character")
     704             :     bool mRespectClusters;
     705             :     // Whether to check user-select style value - if this is included, checks
     706             :     // if user-select is all, then, it may return CONTINUE_UNSELECTABLE.
     707             :     bool mIgnoreUserStyleAll;
     708             : 
     709             :     PeekOffsetCharacterOptions()
     710             :       : mRespectClusters(true)
     711             :       , mIgnoreUserStyleAll(false)
     712             :     {
     713             :     }
     714             :   };
     715             : 
     716             : protected:
     717             :   friend class nsBlockFrame; // for access to DestroyFrom
     718             : 
     719             :   /**
     720             :    * Return true if the frame is part of a Selection.
     721             :    * Helper method to implement the public IsSelected() API.
     722             :    */
     723             :   virtual bool IsFrameSelected() const;
     724             : 
     725             :   /**
     726             :    * Implements Destroy(). Do not call this directly except from within a
     727             :    * DestroyFrom() implementation.
     728             :    *
     729             :    * @note This will always be called, so it is not necessary to override
     730             :    *       Destroy() in subclasses of nsFrame, just DestroyFrom().
     731             :    *
     732             :    * @param  aDestructRoot is the root of the subtree being destroyed
     733             :    */
     734             :   virtual void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) = 0;
     735             :   friend class nsFrameList; // needed to pass aDestructRoot through to children
     736             :   friend class nsLineBox;   // needed to pass aDestructRoot through to children
     737             :   friend class nsContainerFrame; // needed to pass aDestructRoot through to children
     738             :   friend class nsFrame; // need to assign mParent
     739             :   template<class Source> friend class do_QueryFrameHelper; // to read mClass
     740             : public:
     741             : 
     742             :   /**
     743             :    * Get the content object associated with this frame. Does not add a reference.
     744             :    */
     745           2 :   nsIContent* GetContent() const { return mContent; }
     746             : 
     747             :   /**
     748             :    * Get the frame that should be the parent for the frames of child elements
     749             :    * May return nullptr during reflow
     750             :    */
     751             :   virtual nsContainerFrame* GetContentInsertionFrame() { return nullptr; }
     752             : 
     753             :   /**
     754             :    * Move any frames on our overflow list to the end of our principal list.
     755             :    * @return true if there were any overflow frames
     756             :    */
     757             :   virtual bool DrainSelfOverflowList() { return false; }
     758             : 
     759             :   /**
     760             :    * Get the frame that should be scrolled if the content associated
     761             :    * with this frame is targeted for scrolling. For frames implementing
     762             :    * nsIScrollableFrame this will return the frame itself. For frames
     763             :    * like nsTextControlFrame that contain a scrollframe, will return
     764             :    * that scrollframe.
     765             :    */
     766             :   virtual nsIScrollableFrame* GetScrollTargetFrame() { return nullptr; }
     767             : 
     768             :   /**
     769             :    * Get the offsets of the frame. most will be 0,0
     770             :    *
     771             :    */
     772             :   virtual nsresult GetOffsets(int32_t &start, int32_t &end) const = 0;
     773             : 
     774             :   /**
     775             :    * Reset the offsets when splitting frames during Bidi reordering
     776             :    *
     777             :    */
     778             :   virtual void AdjustOffsetsForBidi(int32_t aStart, int32_t aEnd) {}
     779             : 
     780             :   /**
     781             :    * Get the style associated with this frame.
     782             :    */
     783           2 :   ComputedStyle* Style() const { return mComputedStyle; }
     784             :   void SetComputedStyle(ComputedStyle* aStyle)
     785             :   {
     786             :     if (aStyle != mComputedStyle) {
     787             :       MOZ_DIAGNOSTIC_ASSERT(PresShell() == aStyle->PresContextForFrame()->PresShell());
     788             :       RefPtr<ComputedStyle> oldComputedStyle = mComputedStyle.forget();
     789             :       mComputedStyle = aStyle;
     790             :       DidSetComputedStyle(oldComputedStyle);
     791             :     }
     792             :   }
     793             : 
     794             :   /**
     795             :    * SetComputedStyleWithoutNotification is for changes to the style
     796             :    * context that should suppress style change processing, in other
     797             :    * words, those that aren't really changes.  This generally means only
     798             :    * changes that happen during frame construction.
     799             :    */
     800             :   void SetComputedStyleWithoutNotification(ComputedStyle* aStyle)
     801             :   {
     802             :     if (aStyle != mComputedStyle) {
     803             :       MOZ_DIAGNOSTIC_ASSERT(PresShell() == aStyle->PresContextForFrame()->PresShell());
     804             :       mComputedStyle = aStyle;
     805             :     }
     806             :   }
     807             : 
     808             :   // Style post processing hook
     809             :   // Attention: the old style is the one we're forgetting,
     810             :   // and hence possibly completely bogus for GetStyle* purposes.
     811             :   // Use PeekStyleData instead.
     812             :   virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) = 0;
     813             : 
     814             :   /**
     815             :    * Define typesafe getter functions for each style struct by
     816             :    * preprocessing the list of style structs.  These functions are the
     817             :    * preferred way to get style data.  The macro creates functions like:
     818             :    *   const nsStyleBorder* StyleBorder();
     819             :    *   const nsStyleColor* StyleColor();
     820             :    *
     821             :    * Callers outside of libxul should use nsIDOMWindow::GetComputedStyle()
     822             :    * instead of these accessors.
     823             :    *
     824             :    * Callers can use Style*WithOptionalParam if they're in a function that
     825             :    * accepts an *optional* pointer the style struct.
     826             :    */
     827             :   #define STYLE_STRUCT(name_)                                         \
     828             :     const nsStyle##name_ * Style##name_ () const MOZ_NONNULL_RETURN { \
     829             :       NS_ASSERTION(mComputedStyle, "No style found!");                \
     830             :       return mComputedStyle->Style##name_ ();                         \
     831             :     }                                                                 \
     832             :     const nsStyle##name_ * Style##name_##WithOptionalParam(           \
     833             :       const nsStyle##name_ * aStyleStruct) const MOZ_NONNULL_RETURN { \
     834             :       if (aStyleStruct) {                                             \
     835             :         MOZ_ASSERT(aStyleStruct == Style##name_());                   \
     836             :         return aStyleStruct;                                          \
     837             :       }                                                               \
     838             :       return Style##name_();                                          \
     839             :     }
     840             :   #include "nsStyleStructList.h"
     841             :   #undef STYLE_STRUCT
     842             : 
     843             :   /** Also forward GetVisitedDependentColor to the style */
     844             :   template<typename T, typename S>
     845             :   nscolor GetVisitedDependentColor(T S::* aField)
     846             :     { return mComputedStyle->GetVisitedDependentColor(aField); }
     847             : 
     848             :   /**
     849             :    * These methods are to access any additional ComputedStyles that
     850             :    * the frame may be holding.
     851             :    *
     852             :    * These are styles that are children of the frame's primary style and are NOT
     853             :    * used as styles for any child frames.
     854             :    *
     855             :    * These contexts also MUST NOT have any child styles whatsoever. If you need
     856             :    * to insert styles into the style tree, then you should create pseudo element
     857             :    * frames to own them.
     858             :    *
     859             :    * The indicies must be consecutive and implementations MUST return null if
     860             :    * asked for an index that is out of range.
     861             :    */
     862             :   virtual ComputedStyle* GetAdditionalComputedStyle(int32_t aIndex) const = 0;
     863             : 
     864             :   virtual void SetAdditionalComputedStyle(int32_t aIndex,
     865             :                                           ComputedStyle* aComputedStyle) = 0;
     866             : 
     867             :   already_AddRefed<ComputedStyle> ComputeSelectionStyle() const;
     868             : 
     869             :   /**
     870             :    * Accessor functions for geometric parent.
     871             :    */
     872             :   nsContainerFrame* GetParent() const { return mParent; }
     873             : 
     874             :   /**
     875             :    * Gets the parent of a frame, using the parent of the placeholder for
     876             :    * out-of-flow frames.
     877             :    *
     878             :    * This is effectively the primary frame (or one of the continuations) of the
     879             :    * closest flattened tree ancestor that has a frame (flattened tree ancestors
     880             :    * may not have frames in presence of display: contents).
     881             :    */
     882             :   inline nsContainerFrame* GetInFlowParent() const;
     883             : 
     884             :   /**
     885             :    * Return the placeholder for this frame (which must be out-of-flow).
     886             :    * @note this will only return non-null if |this| is the first-in-flow
     887             :    * although we don't assert that here for legacy reasons.
     888             :    */
     889             :   inline nsPlaceholderFrame* GetPlaceholderFrame() const {
     890             :     MOZ_ASSERT(HasAnyStateBits(NS_FRAME_OUT_OF_FLOW));
     891             :     return GetProperty(PlaceholderFrameProperty());
     892             :   }
     893             : 
     894             :   /**
     895             :    * Set this frame's parent to aParent.
     896             :    * If the frame may have moved into or out of a scrollframe's
     897             :    * frame subtree, StickyScrollContainer::NotifyReparentedFrameAcrossScrollFrameBoundary
     898             :    * must also be called.
     899             :    */
     900             :   void SetParent(nsContainerFrame* aParent);
     901             : 
     902             :   /**
     903             :    * The frame's writing-mode, used for logical layout computations.
     904             :    * It's usually the 'writing-mode' computed value, but there are exceptions:
     905             :    *   * inner table frames copy the value from the table frame
     906             :    *     (@see nsTableRowGroupFrame::Init, nsTableRowFrame::Init etc)
     907             :    *   * the root element frame propagates its value to its ancestors
     908             :    *     (@see nsCanvasFrame::MaybePropagateRootElementWritingMode)
     909             :    *   * a scrolled frame propagates its value to its ancestor scroll frame
     910             :    *     (@see nsHTMLScrollFrame::ReloadChildFrames)
     911             :    */
     912             :   mozilla::WritingMode GetWritingMode() const { return mWritingMode; }
     913             : 
     914             :   /**
     915             :    * Construct a writing mode for line layout in this frame.  This is
     916             :    * the writing mode of this frame, except that if this frame is styled with
     917             :    * unicode-bidi:plaintext, we reset the direction to the resolved paragraph
     918             :    * level of the given subframe (typically the first frame on the line),
     919             :    * because the container frame could be split by hard line breaks into
     920             :    * multiple paragraphs with different base direction.
     921             :    * @param aSelfWM the WM of 'this'
     922             :    */
     923             :   mozilla::WritingMode WritingModeForLine(mozilla::WritingMode aSelfWM,
     924             :                                           nsIFrame* aSubFrame) const;
     925             : 
     926             :   /**
     927             :    * Bounding rect of the frame.
     928             :    *
     929             :    * For frames that are laid out according to CSS box model rules the values
     930             :    * are in app units, and the origin is relative to the upper-left of the
     931             :    * geometric parent.  The size includes the content area, borders, and
     932             :    * padding.
     933             :    *
     934             :    * Frames that are laid out according to SVG's coordinate space based rules
     935             :    * (frames with the NS_FRAME_SVG_LAYOUT bit set, which *excludes*
     936             :    * nsSVGOuterSVGFrame) are different.  Many frames of this type do not set or
     937             :    * use mRect, in which case the frame rect is undefined.  The exceptions are:
     938             :    *
     939             :    *   - nsSVGInnerSVGFrame
     940             :    *   - SVGGeometryFrame (used for <path>, <circle>, etc.)
     941             :    *   - nsSVGImageFrame
     942             :    *   - nsSVGForeignObjectFrame
     943             :    *
     944             :    * For these frames the frame rect contains the frame's element's userspace
     945             :    * bounds including fill, stroke and markers, but converted to app units
     946             :    * rather than being in user units (CSS px).  In the SVG code "userspace" is
     947             :    * defined to be the coordinate system for the attributes that define an
     948             :    * element's geometry (such as the 'cx' attribute for <circle>).  For more
     949             :    * precise details see these frames' implementations of the ReflowSVG method
     950             :    * where mRect is set.
     951             :    *
     952             :    * Note: moving or sizing the frame does not affect the view's size or
     953             :    * position.
     954             :    */
     955           0 :   nsRect GetRect() const { return mRect; }
     956             :   nsPoint GetPosition() const { return mRect.TopLeft(); }
     957           0 :   nsSize GetSize() const { return mRect.Size(); }
     958           0 :   nsRect GetRectRelativeToSelf() const {
     959           0 :     return nsRect(nsPoint(0, 0), mRect.Size());
     960             :   }
     961             :   /**
     962             :    * Dimensions and position in logical coordinates in the frame's writing mode
     963             :    *  or another writing mode
     964             :    */
     965             :   mozilla::LogicalRect GetLogicalRect(const nsSize& aContainerSize) const {
     966             :     return GetLogicalRect(GetWritingMode(), aContainerSize);
     967             :   }
     968             :   mozilla::LogicalPoint GetLogicalPosition(const nsSize& aContainerSize) const {
     969             :     return GetLogicalPosition(GetWritingMode(), aContainerSize);
     970             :   }
     971             :   mozilla::LogicalSize GetLogicalSize() const {
     972             :     return GetLogicalSize(GetWritingMode());
     973             :   }
     974             :   mozilla::LogicalRect GetLogicalRect(mozilla::WritingMode aWritingMode,
     975             :                                       const nsSize& aContainerSize) const {
     976             :     return mozilla::LogicalRect(aWritingMode, GetRect(), aContainerSize);
     977             :   }
     978             :   mozilla::LogicalPoint GetLogicalPosition(mozilla::WritingMode aWritingMode,
     979             :                                            const nsSize& aContainerSize) const {
     980             :     return GetLogicalRect(aWritingMode, aContainerSize).Origin(aWritingMode);
     981             :   }
     982             :   mozilla::LogicalSize GetLogicalSize(mozilla::WritingMode aWritingMode) const {
     983             :     return mozilla::LogicalSize(aWritingMode, GetSize());
     984             :   }
     985             :   nscoord IStart(const nsSize& aContainerSize) const {
     986             :     return IStart(GetWritingMode(), aContainerSize);
     987             :   }
     988             :   nscoord IStart(mozilla::WritingMode aWritingMode,
     989             :                  const nsSize& aContainerSize) const {
     990             :     return GetLogicalPosition(aWritingMode, aContainerSize).I(aWritingMode);
     991             :   }
     992             :   nscoord BStart(const nsSize& aContainerSize) const {
     993             :     return BStart(GetWritingMode(), aContainerSize);
     994             :   }
     995             :   nscoord BStart(mozilla::WritingMode aWritingMode,
     996             :                  const nsSize& aContainerSize) const {
     997             :     return GetLogicalPosition(aWritingMode, aContainerSize).B(aWritingMode);
     998             :   }
     999             :   nscoord ISize() const { return ISize(GetWritingMode()); }
    1000             :   nscoord ISize(mozilla::WritingMode aWritingMode) const {
    1001             :     return GetLogicalSize(aWritingMode).ISize(aWritingMode);
    1002             :   }
    1003             :   nscoord BSize() const { return BSize(GetWritingMode()); }
    1004             :   nscoord BSize(mozilla::WritingMode aWritingMode) const {
    1005             :     return GetLogicalSize(aWritingMode).BSize(aWritingMode);
    1006             :   }
    1007             :   nscoord ContentBSize() const { return ContentBSize(GetWritingMode()); }
    1008             :   nscoord ContentBSize(mozilla::WritingMode aWritingMode) const {
    1009             :     auto bp = GetLogicalUsedBorderAndPadding(aWritingMode);
    1010             :     bp.ApplySkipSides(GetLogicalSkipSides());
    1011             :     return std::max(0, BSize(aWritingMode) - bp.BStartEnd(aWritingMode));
    1012             :   }
    1013             : 
    1014             :   /**
    1015             :    * When we change the size of the frame's border-box rect, we may need to
    1016             :    * reset the overflow rect if it was previously stored as deltas.
    1017             :    * (If it is currently a "large" overflow and could be re-packed as deltas,
    1018             :    * we don't bother as the cost of the allocation has already been paid.)
    1019             :    * @param aRebuildDisplayItems If true, then adds this frame to the
    1020             :    * list of modified frames for display list building if the rect has changed.
    1021             :    * Only pass false if you're sure that the relevant display items will be rebuilt
    1022             :    * already (possibly by an ancestor being in the modified list), or if this is
    1023             :    * a temporary change.
    1024             :    */
    1025             :   void SetRect(const nsRect& aRect, bool aRebuildDisplayItems = true) {
    1026             :     if (aRect == mRect) {
    1027             :       return;
    1028             :     }
    1029             :     if (mOverflow.mType != NS_FRAME_OVERFLOW_LARGE &&
    1030             :         mOverflow.mType != NS_FRAME_OVERFLOW_NONE) {
    1031             :       nsOverflowAreas overflow = GetOverflowAreas();
    1032             :       mRect = aRect;
    1033             :       SetOverflowAreas(overflow);
    1034             :     } else {
    1035             :       mRect = aRect;
    1036             :     }
    1037             :     if (aRebuildDisplayItems) {
    1038             :       MarkNeedsDisplayItemRebuild();
    1039             :     }
    1040             :   }
    1041             :   /**
    1042             :    * Set this frame's rect from a logical rect in its own writing direction
    1043             :    */
    1044             :   void SetRect(const mozilla::LogicalRect& aRect,
    1045             :                const nsSize& aContainerSize) {
    1046             :     SetRect(GetWritingMode(), aRect, aContainerSize);
    1047             :   }
    1048             :   /**
    1049             :    * Set this frame's rect from a logical rect in a different writing direction
    1050             :    * (GetPhysicalRect will assert if the writing mode doesn't match)
    1051             :    */
    1052             :   void SetRect(mozilla::WritingMode aWritingMode,
    1053             :                const mozilla::LogicalRect& aRect,
    1054             :                const nsSize& aContainerSize) {
    1055             :     SetRect(aRect.GetPhysicalRect(aWritingMode, aContainerSize));
    1056             :   }
    1057             : 
    1058             :   /**
    1059             :    * Set this frame's size from a logical size in its own writing direction.
    1060             :    * This leaves the frame's logical position unchanged, which means its
    1061             :    * physical position may change (for right-to-left modes).
    1062             :    */
    1063             :   void SetSize(const mozilla::LogicalSize& aSize) {
    1064             :     SetSize(GetWritingMode(), aSize);
    1065             :   }
    1066             :   /*
    1067             :    * Set this frame's size from a logical size in a different writing direction.
    1068             :    * This leaves the frame's logical position in the given mode unchanged,
    1069             :    * which means its physical position may change (for right-to-left modes).
    1070             :    */
    1071             :   void SetSize(mozilla::WritingMode aWritingMode,
    1072             :                const mozilla::LogicalSize& aSize)
    1073             :   {
    1074             :     if ((!aWritingMode.IsVertical() && !aWritingMode.IsBidiLTR()) ||
    1075             :         aWritingMode.IsVerticalRL()) {
    1076             :       nscoord oldWidth = mRect.Width();
    1077             :       SetSize(aSize.GetPhysicalSize(aWritingMode));
    1078             :       mRect.x -= mRect.Width() - oldWidth;
    1079             :     } else {
    1080             :       SetSize(aSize.GetPhysicalSize(aWritingMode));
    1081             :     }
    1082             :   }
    1083             : 
    1084             :   /**
    1085             :    * Set this frame's physical size. This leaves the frame's physical position
    1086             :    * (topLeft) unchanged.
    1087             :    * @param aRebuildDisplayItems If true, then adds this frame to the
    1088             :    * list of modified frames for display list building if the size has changed.
    1089             :    * Only pass false if you're sure that the relevant display items will be rebuilt
    1090             :    * already (possibly by an ancestor being in the modified list), or if this is
    1091             :    * a temporary change.
    1092             :    */
    1093             :   void SetSize(const nsSize& aSize, bool aRebuildDisplayItems = true) {
    1094             :     SetRect(nsRect(mRect.TopLeft(), aSize), aRebuildDisplayItems);
    1095             :   }
    1096             : 
    1097             :   void SetPosition(const nsPoint& aPt) {
    1098             :     if (mRect.TopLeft() == aPt) {
    1099             :       return;
    1100             :     }
    1101             :     mRect.MoveTo(aPt);
    1102             :     MarkNeedsDisplayItemRebuild();
    1103             :   }
    1104             :   void SetPosition(mozilla::WritingMode aWritingMode,
    1105             :                    const mozilla::LogicalPoint& aPt,
    1106             :                    const nsSize& aContainerSize) {
    1107             :     // We subtract mRect.Size() from the container size to account for
    1108             :     // the fact that logical origins in RTL coordinate systems are at
    1109             :     // the top right of the frame instead of the top left.
    1110             :     SetPosition(aPt.GetPhysicalPoint(aWritingMode,
    1111             :                                     aContainerSize - mRect.Size()));
    1112             :   }
    1113             : 
    1114             :   /**
    1115             :    * Move the frame, accounting for relative positioning. Use this when
    1116             :    * adjusting the frame's position by a known amount, to properly update its
    1117             :    * saved normal position (see GetNormalPosition below).
    1118             :    *
    1119             :    * This must be used only when moving a frame *after*
    1120             :    * ReflowInput::ApplyRelativePositioning is called.  When moving
    1121             :    * a frame during the reflow process prior to calling
    1122             :    * ReflowInput::ApplyRelativePositioning, the position should
    1123             :    * simply be adjusted directly (e.g., using SetPosition()).
    1124             :    */
    1125             :   void MovePositionBy(const nsPoint& aTranslation);
    1126             : 
    1127             :   /**
    1128             :    * As above, using a logical-point delta in a given writing mode.
    1129             :    */
    1130             :   void MovePositionBy(mozilla::WritingMode aWritingMode,
    1131             :                       const mozilla::LogicalPoint& aTranslation)
    1132             :   {
    1133             :     // The LogicalPoint represents a vector rather than a point within a
    1134             :     // rectangular coordinate space, so we use a null containerSize when
    1135             :     // converting logical to physical.
    1136             :     const nsSize nullContainerSize;
    1137             :     MovePositionBy(aTranslation.GetPhysicalPoint(aWritingMode,
    1138             :                                                  nullContainerSize));
    1139             :   }
    1140             : 
    1141             :   /**
    1142             :    * Return frame's rect without relative positioning
    1143             :    */
    1144             :   nsRect GetNormalRect() const;
    1145             : 
    1146             :   /**
    1147             :    * Return frame's position without relative positioning.
    1148             :    * If aHasProperty is provided, returns whether the normal position
    1149             :    * was stored in a frame property.
    1150             :    */
    1151             :   inline nsPoint GetNormalPosition(bool* aHasProperty = nullptr) const;
    1152             : 
    1153             :   mozilla::LogicalPoint
    1154             :   GetLogicalNormalPosition(mozilla::WritingMode aWritingMode,
    1155             :                            const nsSize& aContainerSize) const
    1156             :   {
    1157             :     // Subtract the size of this frame from the container size to get
    1158             :     // the correct position in rtl frames where the origin is on the
    1159             :     // right instead of the left
    1160             :     return mozilla::LogicalPoint(aWritingMode,
    1161             :                                  GetNormalPosition(),
    1162             :                                  aContainerSize - mRect.Size());
    1163             :   }
    1164             : 
    1165             :   virtual nsPoint GetPositionOfChildIgnoringScrolling(const nsIFrame* aChild)
    1166             :   { return aChild->GetPosition(); }
    1167             : 
    1168             :   nsPoint GetPositionIgnoringScrolling() const;
    1169             : 
    1170             :   typedef AutoTArray<nsDisplayItem*, 4> DisplayItemArray;
    1171             : 
    1172             : #define NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(prop, type, dtor)             \
    1173             :   static const mozilla::FramePropertyDescriptor<type>* prop() {           \
    1174             :     /* Use of constexpr caused startup crashes with MSVC2015u1 PGO. */    \
    1175             :     static const auto descriptor =                                        \
    1176             :       mozilla::FramePropertyDescriptor<type>::NewWithDestructor<dtor>();  \
    1177             :     return &descriptor;                                                   \
    1178             :   }
    1179             : 
    1180             : // Don't use this unless you really know what you're doing!
    1181             : #define NS_DECLARE_FRAME_PROPERTY_WITH_FRAME_IN_DTOR(prop, type, dtor)    \
    1182             :   static const mozilla::FramePropertyDescriptor<type>* prop() {           \
    1183             :     /* Use of constexpr caused startup crashes with MSVC2015u1 PGO. */    \
    1184             :     static const auto descriptor = mozilla::                              \
    1185             :       FramePropertyDescriptor<type>::NewWithDestructorWithFrame<dtor>();  \
    1186             :     return &descriptor;                                                   \
    1187             :   }
    1188             : 
    1189             : #define NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(prop, type)                \
    1190             :   static const mozilla::FramePropertyDescriptor<type>* prop() {           \
    1191             :     /* Use of constexpr caused startup crashes with MSVC2015u1 PGO. */    \
    1192             :     static const auto descriptor =                                        \
    1193             :       mozilla::FramePropertyDescriptor<type>::NewWithoutDestructor();     \
    1194             :     return &descriptor;                                                   \
    1195             :   }
    1196             : 
    1197             : #define NS_DECLARE_FRAME_PROPERTY_DELETABLE(prop, type) \
    1198             :   NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(prop, type, DeleteValue)
    1199             : 
    1200             : #define NS_DECLARE_FRAME_PROPERTY_RELEASABLE(prop, type) \
    1201             :   NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(prop, type, ReleaseValue)
    1202             : 
    1203             : #define NS_DECLARE_FRAME_PROPERTY_WITH_DTOR_NEVER_CALLED(prop, type)  \
    1204             :   static void AssertOnDestroyingProperty##prop(type*) {               \
    1205             :     MOZ_ASSERT_UNREACHABLE("Frame property " #prop " should never "   \
    1206             :                            "be destroyed by the FrameProperties class");  \
    1207             :   }                                                                   \
    1208             :   NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(prop, type,                     \
    1209             :                                       AssertOnDestroyingProperty##prop)
    1210             : 
    1211             : #define NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(prop, type) \
    1212             :   NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(prop, mozilla::SmallValueHolder<type>)
    1213             : 
    1214             :   NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(IBSplitSibling, nsContainerFrame)
    1215             :   NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(IBSplitPrevSibling, nsContainerFrame)
    1216             : 
    1217             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(NormalPositionProperty, nsPoint)
    1218             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(ComputedOffsetProperty, nsMargin)
    1219             : 
    1220             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(OutlineInnerRectProperty, nsRect)
    1221             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(PreEffectsBBoxProperty, nsRect)
    1222             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(PreTransformOverflowAreasProperty,
    1223             :                                       nsOverflowAreas)
    1224             : 
    1225             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(OverflowAreasProperty, nsOverflowAreas)
    1226             : 
    1227             :   // The initial overflow area passed to FinishAndStoreOverflow. This is only set
    1228             :   // on frames that Preserve3D() or HasPerspective() or IsTransformed(), and
    1229             :   // when at least one of the overflow areas differs from the frame bound rect.
    1230             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(InitialOverflowProperty, nsOverflowAreas)
    1231             : 
    1232             : #ifdef DEBUG
    1233             :   // InitialOverflowPropertyDebug is added to the frame to indicate that either
    1234             :   // the InitialOverflowProperty has been stored or the InitialOverflowProperty
    1235             :   // has been suppressed due to being set to the default value (frame bounds)
    1236             :   NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(DebugInitialOverflowPropertyApplied, bool)
    1237             : #endif
    1238             : 
    1239             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(UsedMarginProperty, nsMargin)
    1240             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(UsedPaddingProperty, nsMargin)
    1241             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(UsedBorderProperty, nsMargin)
    1242             : 
    1243             :   NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(LineBaselineOffset, nscoord)
    1244             : 
    1245             :   // Temporary override for a flex item's main-size property (either width
    1246             :   // or height), imposed by its flex container.
    1247             :   NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(FlexItemMainSizeOverride, nscoord)
    1248             : 
    1249             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(InvalidationRect, nsRect)
    1250             : 
    1251             :   NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(RefusedAsyncAnimationProperty, bool)
    1252             : 
    1253             :   NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(FragStretchBSizeProperty, nscoord)
    1254             : 
    1255             :   // The block-axis margin-box size associated with eBClampMarginBoxMinSize.
    1256             :   NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(BClampMarginBoxMinSizeProperty, nscoord)
    1257             : 
    1258             :   NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(IBaselinePadProperty, nscoord)
    1259             :   NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(BBaselinePadProperty, nscoord)
    1260             : 
    1261             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(ModifiedFrameList, nsTArray<nsIFrame*>)
    1262             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(OverriddenDirtyRectFrameList, nsTArray<nsIFrame*>)
    1263             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(DisplayItems, DisplayItemArray)
    1264             : 
    1265             :   NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(BidiDataProperty, mozilla::FrameBidiData)
    1266             : 
    1267             :   NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(PlaceholderFrameProperty, nsPlaceholderFrame)
    1268             : 
    1269             :   mozilla::FrameBidiData GetBidiData() const
    1270             :   {
    1271             :     bool exists;
    1272             :     mozilla::FrameBidiData bidiData = GetProperty(BidiDataProperty(), &exists);
    1273             :     if (!exists) {
    1274             :       bidiData.precedingControl = mozilla::kBidiLevelNone;
    1275             :     }
    1276             :     return bidiData;
    1277             :   }
    1278             : 
    1279             :   nsBidiLevel GetBaseLevel() const
    1280             :   {
    1281             :     return GetBidiData().baseLevel;
    1282             :   }
    1283             : 
    1284             :   nsBidiLevel GetEmbeddingLevel() const
    1285             :   {
    1286             :     return GetBidiData().embeddingLevel;
    1287             :   }
    1288             : 
    1289             :   /**
    1290             :    * Return the distance between the border edge of the frame and the
    1291             :    * margin edge of the frame.  Like GetRect(), returns the dimensions
    1292             :    * as of the most recent reflow.
    1293             :    *
    1294             :    * This doesn't include any margin collapsing that may have occurred.
    1295             :    *
    1296             :    * It also treats 'auto' margins as zero, and treats any margins that
    1297             :    * should have been turned into 'auto' because of overconstraint as
    1298             :    * having their original values.
    1299             :    */
    1300             :   virtual nsMargin GetUsedMargin() const;
    1301             :   virtual mozilla::LogicalMargin
    1302             :   GetLogicalUsedMargin(mozilla::WritingMode aWritingMode) const {
    1303             :     return mozilla::LogicalMargin(aWritingMode, GetUsedMargin());
    1304             :   }
    1305             : 
    1306             :   /**
    1307             :    * Return the distance between the border edge of the frame (which is
    1308             :    * its rect) and the padding edge of the frame. Like GetRect(), returns
    1309             :    * the dimensions as of the most recent reflow.
    1310             :    *
    1311             :    * Note that this differs from StyleBorder()->GetComputedBorder() in
    1312             :    * that this describes a region of the frame's box, and
    1313             :    * StyleBorder()->GetComputedBorder() describes a border.  They differ
    1314             :    * for tables (particularly border-collapse tables) and themed
    1315             :    * elements.
    1316             :    */
    1317             :   virtual nsMargin GetUsedBorder() const;
    1318             :   virtual mozilla::LogicalMargin
    1319             :   GetLogicalUsedBorder(mozilla::WritingMode aWritingMode) const {
    1320             :     return mozilla::LogicalMargin(aWritingMode, GetUsedBorder());
    1321             :   }
    1322             : 
    1323             :   /**
    1324             :    * Return the distance between the padding edge of the frame and the
    1325             :    * content edge of the frame.  Like GetRect(), returns the dimensions
    1326             :    * as of the most recent reflow.
    1327             :    */
    1328             :   virtual nsMargin GetUsedPadding() const;
    1329             :   virtual mozilla::LogicalMargin
    1330             :   GetLogicalUsedPadding(mozilla::WritingMode aWritingMode) const {
    1331             :     return mozilla::LogicalMargin(aWritingMode, GetUsedPadding());
    1332             :   }
    1333             : 
    1334             :   nsMargin GetUsedBorderAndPadding() const {
    1335             :     return GetUsedBorder() + GetUsedPadding();
    1336             :   }
    1337             :   mozilla::LogicalMargin
    1338             :   GetLogicalUsedBorderAndPadding(mozilla::WritingMode aWritingMode) const {
    1339             :     return mozilla::LogicalMargin(aWritingMode, GetUsedBorderAndPadding());
    1340             :   }
    1341             : 
    1342             :   /**
    1343             :    * Like the frame's rect (see |GetRect|), which is the border rect,
    1344             :    * other rectangles of the frame, in app units, relative to the parent.
    1345             :    */
    1346             :   nsRect GetPaddingRect() const;
    1347             :   nsRect GetPaddingRectRelativeToSelf() const;
    1348             :   nsRect GetContentRect() const;
    1349             :   nsRect GetContentRectRelativeToSelf() const;
    1350             :   nsRect GetMarginRectRelativeToSelf() const;
    1351             : 
    1352             :   /**
    1353             :    * The area to paint box-shadows around.  The default is the border rect.
    1354             :    * (nsFieldSetFrame overrides this).
    1355             :    */
    1356             :   virtual nsRect VisualBorderRectRelativeToSelf() const {
    1357             :     return nsRect(0, 0, mRect.Width(), mRect.Height());
    1358             :   }
    1359             : 
    1360             :   /**
    1361             :    * Get the size, in app units, of the border radii. It returns FALSE iff all
    1362             :    * returned radii == 0 (so no border radii), TRUE otherwise.
    1363             :    * For the aRadii indexes, use the enum HalfCorner constants in gfx/2d/Types.h
    1364             :    * If a side is skipped via aSkipSides, its corners are forced to 0.
    1365             :    *
    1366             :    * All corner radii are then adjusted so they do not require more
    1367             :    * space than aBorderArea, according to the algorithm in css3-background.
    1368             :    *
    1369             :    * aFrameSize is used as the basis for percentage widths and heights.
    1370             :    * aBorderArea is used for the adjustment of radii that might be too
    1371             :    * large.
    1372             :    * FIXME: In the long run, we can probably get away with only one of
    1373             :    * these, especially if we change the way we handle outline-radius (by
    1374             :    * removing it and inflating the border radius)
    1375             :    *
    1376             :    * Return whether any radii are nonzero.
    1377             :    */
    1378             :   static bool ComputeBorderRadii(const nsStyleCorners& aBorderRadius,
    1379             :                                  const nsSize& aFrameSize,
    1380             :                                  const nsSize& aBorderArea,
    1381             :                                  Sides aSkipSides,
    1382             :                                  nscoord aRadii[8]);
    1383             : 
    1384             :   /*
    1385             :    * Given a set of border radii for one box (e.g., border box), convert
    1386             :    * it to the equivalent set of radii for another box (e.g., in to
    1387             :    * padding box, out to outline box) by reducing radii or increasing
    1388             :    * nonzero radii as appropriate.
    1389             :    *
    1390             :    * Indices into aRadii are the enum HalfCorner constants in gfx/2d/Types.h
    1391             :    *
    1392             :    * Note that InsetBorderRadii is lossy, since it can turn nonzero
    1393             :    * radii into zero, and OutsetBorderRadii does not inflate zero radii.
    1394             :    * Therefore, callers should always inset or outset directly from the
    1395             :    * original value coming from style.
    1396             :    */
    1397             :   static void InsetBorderRadii(nscoord aRadii[8], const nsMargin &aOffsets);
    1398             :   static void OutsetBorderRadii(nscoord aRadii[8], const nsMargin &aOffsets);
    1399             : 
    1400             :   /**
    1401             :    * Fill in border radii for this frame.  Return whether any are nonzero.
    1402             :    * Indices into aRadii are the enum HalfCorner constants in gfx/2d/Types.h
    1403             :    * aSkipSides is a union of eSideBitsLeft/Right/Top/Bottom bits that says
    1404             :    * which side(s) to skip.
    1405             :    *
    1406             :    * Note: GetMarginBoxBorderRadii() and GetShapeBoxBorderRadii() work only
    1407             :    * on frames that establish block formatting contexts since they don't
    1408             :    * participate in margin-collapsing.
    1409             :    */
    1410             :   virtual bool GetBorderRadii(const nsSize& aFrameSize,
    1411             :                               const nsSize& aBorderArea,
    1412             :                               Sides aSkipSides,
    1413             :                               nscoord aRadii[8]) const;
    1414             :   bool GetBorderRadii(nscoord aRadii[8]) const;
    1415             :   bool GetMarginBoxBorderRadii(nscoord aRadii[8]) const;
    1416             :   bool GetPaddingBoxBorderRadii(nscoord aRadii[8]) const;
    1417             :   bool GetContentBoxBorderRadii(nscoord aRadii[8]) const;
    1418             :   bool GetBoxBorderRadii(nscoord aRadii[8], nsMargin aOffset, bool aIsOutset) const;
    1419             :   bool GetShapeBoxBorderRadii(nscoord aRadii[8]) const;
    1420             : 
    1421             :   /**
    1422             :    * XXX: this method will likely be replaced by GetVerticalAlignBaseline
    1423             :    * Get the position of the frame's baseline, relative to the top of
    1424             :    * the frame (its top border edge).  Only valid when Reflow is not
    1425             :    * needed.
    1426             :    * @note You should only call this on frames with a WM that's parallel to aWM.
    1427             :    * @param aWM the writing-mode of the alignment context, with the ltr/rtl
    1428             :    * direction tweak done by nsIFrame::GetWritingMode(nsIFrame*) in inline
    1429             :    * contexts (see that method).
    1430             :    */
    1431             :   virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWM) const = 0;
    1432             : 
    1433             :   /**
    1434             :    * Synthesize a first(last) inline-axis baseline from our margin-box.
    1435             :    * An alphabetical baseline is at the start(end) edge and a central baseline
    1436             :    * is at the center of our block-axis margin-box (aWM tells which to use).
    1437             :    * https://drafts.csswg.org/css-align-3/#synthesize-baselines
    1438             :    * @note You should only call this on frames with a WM that's parallel to aWM.
    1439             :    * @param aWM the writing-mode of the alignment context
    1440             :    * @return an offset from our border-box block-axis start(end) edge for
    1441             :    * a first(last) baseline respectively
    1442             :    * (implemented in nsIFrameInlines.h)
    1443             :    */
    1444             :   inline nscoord SynthesizeBaselineBOffsetFromMarginBox(
    1445             :                    mozilla::WritingMode aWM,
    1446             :                    BaselineSharingGroup aGroup) const;
    1447             : 
    1448             :   /**
    1449             :    * Synthesize a first(last) inline-axis baseline from our border-box.
    1450             :    * An alphabetical baseline is at the start(end) edge and a central baseline
    1451             :    * is at the center of our block-axis border-box (aWM tells which to use).
    1452             :    * https://drafts.csswg.org/css-align-3/#synthesize-baselines
    1453             :    * @note The returned value is only valid when reflow is not needed.
    1454             :    * @note You should only call this on frames with a WM that's parallel to aWM.
    1455             :    * @param aWM the writing-mode of the alignment context
    1456             :    * @return an offset from our border-box block-axis start(end) edge for
    1457             :    * a first(last) baseline respectively
    1458             :    * (implemented in nsIFrameInlines.h)
    1459             :    */
    1460             :   inline nscoord SynthesizeBaselineBOffsetFromBorderBox(
    1461             :                    mozilla::WritingMode aWM,
    1462             :                    BaselineSharingGroup aGroup) const;
    1463             : 
    1464             :   /**
    1465             :    * Return the position of the frame's inline-axis baseline, or synthesize one
    1466             :    * for the given alignment context. The returned baseline is the distance from
    1467             :    * the block-axis border-box start(end) edge for aBaselineGroup eFirst(eLast).
    1468             :    * @note The returned value is only valid when reflow is not needed.
    1469             :    * @note You should only call this on frames with a WM that's parallel to aWM.
    1470             :    * @param aWM the writing-mode of the alignment context
    1471             :    * @param aBaselineOffset out-param, only valid if the method returns true
    1472             :    * (implemented in nsIFrameInlines.h)
    1473             :    */
    1474             :   inline nscoord BaselineBOffset(mozilla::WritingMode aWM,
    1475             :                                  BaselineSharingGroup aBaselineGroup,
    1476             :                                  AlignmentContext     aAlignmentContext) const;
    1477             : 
    1478             :   /**
    1479             :    * XXX: this method is taking over the role that GetLogicalBaseline has.
    1480             :    * Return true if the frame has a CSS2 'vertical-align' baseline.
    1481             :    * If it has, then the returned baseline is the distance from the block-
    1482             :    * axis border-box start edge.
    1483             :    * @note This method should only be used in AlignmentContext::eInline contexts.
    1484             :    * @note The returned value is only valid when reflow is not needed.
    1485             :    * @note You should only call this on frames with a WM that's parallel to aWM.
    1486             :    * @param aWM the writing-mode of the alignment context
    1487             :    * @param aBaseline the baseline offset, only valid if the method returns true
    1488             :    */
    1489             :   virtual bool GetVerticalAlignBaseline(mozilla::WritingMode aWM,
    1490             :                                         nscoord* aBaseline) const {
    1491             :     return false;
    1492             :   }
    1493             : 
    1494             :   /**
    1495             :    * Return true if the frame has a first(last) inline-axis natural baseline per
    1496             :    * CSS Box Alignment.  If so, then the returned baseline is the distance from
    1497             :    * the block-axis border-box start(end) edge for aBaselineGroup eFirst(eLast).
    1498             :    * https://drafts.csswg.org/css-align-3/#natural-baseline
    1499             :    * @note The returned value is only valid when reflow is not needed.
    1500             :    * @note You should only call this on frames with a WM that's parallel to aWM.
    1501             :    * @param aWM the writing-mode of the alignment context
    1502             :    * @param aBaseline the baseline offset, only valid if the method returns true
    1503             :    */
    1504             :   virtual bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM,
    1505             :                                          BaselineSharingGroup aBaselineGroup,
    1506             :                                          nscoord*             aBaseline) const {
    1507             :     return false;
    1508             :   }
    1509             : 
    1510             :   /**
    1511             :    * Get the position of the baseline on which the caret needs to be placed,
    1512             :    * relative to the top of the frame.  This is mostly needed for frames
    1513             :    * which return a baseline from GetBaseline which is not useful for
    1514             :    * caret positioning.
    1515             :    */
    1516             :   virtual nscoord GetCaretBaseline() const {
    1517             :     return GetLogicalBaseline(GetWritingMode());
    1518             :   }
    1519             : 
    1520             :   ///////////////////////////////////////////////////////////////////////////////
    1521             :   // The public visibility API.
    1522             :   ///////////////////////////////////////////////////////////////////////////////
    1523             : 
    1524             :   /// @return true if we're tracking visibility for this frame.
    1525             :   bool TrackingVisibility() const
    1526             :   {
    1527             :     return bool(GetStateBits() & NS_FRAME_VISIBILITY_IS_TRACKED);
    1528             :   }
    1529             : 
    1530             :   /// @return the visibility state of this frame. See the Visibility enum
    1531             :   /// for the possible return values and their meanings.
    1532             :   Visibility GetVisibility() const;
    1533             : 
    1534             :   /// Update the visibility state of this frame synchronously.
    1535             :   /// XXX(seth): Avoid using this method; we should be relying on the refresh
    1536             :   /// driver for visibility updates. This method, which replaces
    1537             :   /// nsLayoutUtils::UpdateApproximateFrameVisibility(), exists purely as a
    1538             :   /// temporary measure to avoid changing behavior during the transition from
    1539             :   /// the old image visibility code.
    1540             :   void UpdateVisibilitySynchronously();
    1541             : 
    1542             :   // A frame property which stores the visibility state of this frame. Right
    1543             :   // now that consists of an approximate visibility counter represented as a
    1544             :   // uint32_t. When the visibility of this frame is not being tracked, this
    1545             :   // property is absent.
    1546             :   NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(VisibilityStateProperty, uint32_t);
    1547             : 
    1548             : protected:
    1549             : 
    1550             :   /**
    1551             :    * Subclasses can call this method to enable visibility tracking for this frame.
    1552             :    *
    1553             :    * If visibility tracking was previously disabled, this will schedule an
    1554             :    * update an asynchronous update of visibility.
    1555             :    */
    1556             :   void EnableVisibilityTracking();
    1557             : 
    1558             :   /**
    1559             :    * Subclasses can call this method to disable visibility tracking for this frame.
    1560             :    *
    1561             :    * Note that if visibility tracking was previously enabled, disabling visibility
    1562             :    * tracking will cause a synchronous call to OnVisibilityChange().
    1563             :    */
    1564             :   void DisableVisibilityTracking();
    1565             : 
    1566             :   /**
    1567             :    * Called when a frame transitions between visibility states (for example,
    1568             :    * from nonvisible to visible, or from visible to nonvisible).
    1569             :    *
    1570             :    * @param aNewVisibility    The new visibility state.
    1571             :    * @param aNonvisibleAction A requested action if the frame has become
    1572             :    *                          nonvisible. If Nothing(), no action is
    1573             :    *                          requested. If DISCARD_IMAGES is specified, the
    1574             :    *                          frame is requested to ask any images it's
    1575             :    *                          associated with to discard their surfaces if
    1576             :    *                          possible.
    1577             :    *
    1578             :    * Subclasses which override this method should call their parent class's
    1579             :    * implementation.
    1580             :    */
    1581             :   virtual void OnVisibilityChange(Visibility aNewVisibility,
    1582             :                                   const Maybe<OnNonvisible>& aNonvisibleAction = Nothing());
    1583             : 
    1584             : public:
    1585             : 
    1586             :   ///////////////////////////////////////////////////////////////////////////////
    1587             :   // Internal implementation for the approximate frame visibility API.
    1588             :   ///////////////////////////////////////////////////////////////////////////////
    1589             : 
    1590             :   /**
    1591             :    * We track the approximate visibility of frames using a counter; if it's
    1592             :    * non-zero, then the frame is considered visible. Using a counter allows us
    1593             :    * to account for situations where the frame may be visible in more than one
    1594             :    * place (for example, via -moz-element), and it simplifies the
    1595             :    * implementation of our approximate visibility tracking algorithms.
    1596             :    *
    1597             :    * @param aNonvisibleAction A requested action if the frame has become
    1598             :    *                          nonvisible. If Nothing(), no action is
    1599             :    *                          requested. If DISCARD_IMAGES is specified, the
    1600             :    *                          frame is requested to ask any images it's
    1601             :    *                          associated with to discard their surfaces if
    1602             :    *                          possible.
    1603             :    */
    1604             :   void DecApproximateVisibleCount(const Maybe<OnNonvisible>& aNonvisibleAction = Nothing());
    1605             :   void IncApproximateVisibleCount();
    1606             : 
    1607             : 
    1608             :   /**
    1609             :    * Get the specified child list.
    1610             :    *
    1611             :    * @param   aListID identifies the requested child list.
    1612             :    * @return  the child list.  If the requested list is unsupported by this
    1613             :    *          frame type, an empty list will be returned.
    1614             :    */
    1615             :   virtual const nsFrameList& GetChildList(ChildListID aListID) const = 0;
    1616           0 :   const nsFrameList& PrincipalChildList() const { return GetChildList(kPrincipalList); }
    1617             :   virtual void GetChildLists(nsTArray<ChildList>* aLists) const = 0;
    1618             : 
    1619             :   /**
    1620             :    * Gets the child lists for this frame, including
    1621             :    * ones belong to a child document.
    1622             :    */
    1623             :   void GetCrossDocChildLists(nsTArray<ChildList>* aLists);
    1624             : 
    1625             :   // The individual concrete child lists.
    1626             :   static const ChildListID kPrincipalList = mozilla::layout::kPrincipalList;
    1627             :   static const ChildListID kAbsoluteList = mozilla::layout::kAbsoluteList;
    1628             :   static const ChildListID kBulletList = mozilla::layout::kBulletList;
    1629             :   static const ChildListID kCaptionList = mozilla::layout::kCaptionList;
    1630             :   static const ChildListID kColGroupList = mozilla::layout::kColGroupList;
    1631             :   static const ChildListID kExcessOverflowContainersList = mozilla::layout::kExcessOverflowContainersList;
    1632             :   static const ChildListID kFixedList = mozilla::layout::kFixedList;
    1633             :   static const ChildListID kFloatList = mozilla::layout::kFloatList;
    1634             :   static const ChildListID kOverflowContainersList = mozilla::layout::kOverflowContainersList;
    1635             :   static const ChildListID kOverflowList = mozilla::layout::kOverflowList;
    1636             :   static const ChildListID kOverflowOutOfFlowList = mozilla::layout::kOverflowOutOfFlowList;
    1637             :   static const ChildListID kPopupList = mozilla::layout::kPopupList;
    1638             :   static const ChildListID kPushedFloatsList = mozilla::layout::kPushedFloatsList;
    1639             :   static const ChildListID kSelectPopupList = mozilla::layout::kSelectPopupList;
    1640             :   static const ChildListID kBackdropList = mozilla::layout::kBackdropList;
    1641             :   // A special alias for kPrincipalList that do not request reflow.
    1642             :   static const ChildListID kNoReflowPrincipalList = mozilla::layout::kNoReflowPrincipalList;
    1643             : 
    1644             :   /**
    1645             :    * Child frames are linked together in a doubly-linked list
    1646             :    */
    1647             :   nsIFrame* GetNextSibling() const { return mNextSibling; }
    1648             :   void SetNextSibling(nsIFrame* aNextSibling) {
    1649             :     NS_ASSERTION(this != aNextSibling, "Creating a circular frame list, this is very bad.");
    1650             :     if (mNextSibling && mNextSibling->GetPrevSibling() == this) {
    1651             :       mNextSibling->mPrevSibling = nullptr;
    1652             :     }
    1653             :     mNextSibling = aNextSibling;
    1654             :     if (mNextSibling) {
    1655             :       mNextSibling->mPrevSibling = this;
    1656             :     }
    1657             :   }
    1658             : 
    1659             :   nsIFrame* GetPrevSibling() const { return mPrevSibling; }
    1660             : 
    1661             :   /**
    1662             :    * Builds the display lists for the content represented by this frame
    1663             :    * and its descendants. The background+borders of this element must
    1664             :    * be added first, before any other content.
    1665             :    *
    1666             :    * This should only be called by methods in nsFrame. Instead of calling this
    1667             :    * directly, call either BuildDisplayListForStackingContext or
    1668             :    * BuildDisplayListForChild.
    1669             :    *
    1670             :    * See nsDisplayList.h for more information about display lists.
    1671             :    */
    1672             :   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
    1673             :                                 const nsDisplayListSet& aLists) {}
    1674             :   /**
    1675             :    * Displays the caret onto the given display list builder. The caret is
    1676             :    * painted on top of the rest of the display list items.
    1677             :    */
    1678             :   void DisplayCaret(nsDisplayListBuilder* aBuilder,
    1679             :                     nsDisplayList*        aList);
    1680             : 
    1681             :   /**
    1682             :    * Get the preferred caret color at the offset.
    1683             :    *
    1684             :    * @param aOffset is offset of the content.
    1685             :    */
    1686             :   virtual nscolor GetCaretColorAt(int32_t aOffset);
    1687             : 
    1688             : 
    1689             :   bool IsThemed(nsITheme::Transparency* aTransparencyState = nullptr) const {
    1690             :     return IsThemed(StyleDisplay(), aTransparencyState);
    1691             :   }
    1692             :   bool IsThemed(const nsStyleDisplay* aDisp,
    1693             :                   nsITheme::Transparency* aTransparencyState = nullptr) const {
    1694             :     nsIFrame* mutable_this = const_cast<nsIFrame*>(this);
    1695             :     if (!aDisp->mAppearance)
    1696             :       return false;
    1697             :     nsPresContext* pc = PresContext();
    1698             :     nsITheme *theme = pc->GetTheme();
    1699             :     if(!theme ||
    1700             :        !theme->ThemeSupportsWidget(pc, mutable_this, aDisp->mAppearance))
    1701             :       return false;
    1702             :     if (aTransparencyState) {
    1703             :       *aTransparencyState =
    1704             :         theme->GetWidgetTransparency(mutable_this, aDisp->mAppearance);
    1705             :     }
    1706             :     return true;
    1707             :   }
    1708             : 
    1709             :   /**
    1710             :    * Builds a display list for the content represented by this frame,
    1711             :    * treating this frame as the root of a stacking context.
    1712             :    * Optionally sets aCreatedContainerItem to true if we created a
    1713             :    * single container display item for the stacking context, and no
    1714             :    * other wrapping items are needed.
    1715             :    */
    1716             :   void BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
    1717             :                                           nsDisplayList*        aList,
    1718             :                                           bool*                 aCreatedContainerItem = nullptr);
    1719             : 
    1720             :   enum {
    1721             :     DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT = 0x01,
    1722             :     DISPLAY_CHILD_FORCE_STACKING_CONTEXT = 0x02,
    1723             :     DISPLAY_CHILD_INLINE = 0x04
    1724             :   };
    1725             :   /**
    1726             :    * Adjusts aDirtyRect for the child's offset, checks that the dirty rect
    1727             :    * actually intersects the child (or its descendants), calls BuildDisplayList
    1728             :    * on the child if necessary, and puts things in the right lists if the child
    1729             :    * is positioned.
    1730             :    *
    1731             :    * @param aFlags combination of DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT,
    1732             :    *    DISPLAY_CHILD_FORCE_STACKING_CONTEXT and DISPLAY_CHILD_INLINE
    1733             :    */
    1734             :   void BuildDisplayListForChild(nsDisplayListBuilder*   aBuilder,
    1735             :                                 nsIFrame*               aChild,
    1736             :                                 const nsDisplayListSet& aLists,
    1737             :                                 uint32_t                aFlags = 0);
    1738             : 
    1739           0 :   bool RefusedAsyncAnimation() const
    1740             :   {
    1741           0 :     return GetProperty(RefusedAsyncAnimationProperty());
    1742             :   }
    1743             : 
    1744             :   /**
    1745             :    * Returns true if this frame is transformed (e.g. has CSS or SVG transforms)
    1746             :    * or if its parent is an SVG frame that has children-only transforms (e.g.
    1747             :    * an SVG viewBox attribute) or if its transform-style is preserve-3d or
    1748             :    * the frame has transform animations.
    1749             :    *
    1750             :    * @param aStyleDisplay:  If the caller has this->StyleDisplay(), providing
    1751             :    *   it here will improve performance.
    1752             :    */
    1753             :   bool IsTransformed(const nsStyleDisplay* aStyleDisplay) const;
    1754             :   bool IsTransformed() const {
    1755             :     return IsTransformed(StyleDisplay());
    1756             :   }
    1757             : 
    1758             :   /**
    1759             :    * Same as IsTransformed, except that it doesn't take SVG transforms
    1760             :    * into account.
    1761             :    */
    1762             :   bool IsCSSTransformed(const nsStyleDisplay* aStyleDisplay) const;
    1763             : 
    1764             :   /**
    1765             :    * True if this frame has any animation of transform in effect.
    1766             :    *
    1767             :    */
    1768             :   bool HasAnimationOfTransform() const;
    1769             : 
    1770             :   /**
    1771             :    * Returns true if the frame is translucent or the frame has opacity
    1772             :    * animations for the purposes of creating a stacking context.
    1773             :    *
    1774             :    * @param aEffectSet: This function may need to look up EffectSet property.
    1775             :    *   If a caller already have one, pass it in can save property look up
    1776             :    *   time; otherwise, just left it as nullptr.
    1777             :    */
    1778             :   bool HasOpacity(mozilla::EffectSet* aEffectSet = nullptr) const
    1779             :   {
    1780             :     return HasOpacityInternal(1.0f, aEffectSet);
    1781             :   }
    1782             :   /**
    1783             :    * Returns true if the frame is translucent for display purposes.
    1784             :    *
    1785             :    * @param aEffectSet: This function may need to look up EffectSet property.
    1786             :    *   If a caller already have one, pass it in can save property look up
    1787             :    *   time; otherwise, just left it as nullptr.
    1788             :    */
    1789             :   bool HasVisualOpacity(mozilla::EffectSet* aEffectSet = nullptr) const
    1790             :   {
    1791             :     // Treat an opacity value of 0.99 and above as opaque.  This is an
    1792             :     // optimization aimed at Web content which use opacity:0.99 as a hint for
    1793             :     // creating a stacking context only.
    1794             :     return HasOpacityInternal(0.99f, aEffectSet);
    1795             :   }
    1796             : 
    1797             :    /**
    1798             :    * Return true if this frame might be using a transform getter.
    1799             :    */
    1800             :   virtual bool HasTransformGetter() const { return false; }
    1801             : 
    1802             :   /**
    1803             :    * Returns true if this frame is an SVG frame that has SVG transforms applied
    1804             :    * to it, or if its parent frame is an SVG frame that has children-only
    1805             :    * transforms (e.g. an SVG viewBox attribute).
    1806             :    * If aOwnTransforms is non-null and the frame has its own SVG transforms,
    1807             :    * aOwnTransforms will be set to these transforms. If aFromParentTransforms
    1808             :    * is non-null and the frame has an SVG parent with children-only transforms,
    1809             :    * then aFromParentTransforms will be set to these transforms.
    1810             :    */
    1811             :   virtual bool IsSVGTransformed(Matrix *aOwnTransforms = nullptr,
    1812             :                                 Matrix *aFromParentTransforms = nullptr) const;
    1813             : 
    1814             :   /**
    1815             :    * Returns whether this frame will attempt to extend the 3d transforms of its
    1816             :    * children. This requires transform-style: preserve-3d, as well as no clipping
    1817             :    * or svg effects.
    1818             :    *
    1819             :    * @param aStyleDisplay:  If the caller has this->StyleDisplay(), providing
    1820             :    *   it here will improve performance.
    1821             :    *
    1822             :    * @param aEffectSet: This function may need to look up EffectSet property.
    1823             :    *   If a caller already have one, pass it in can save property look up
    1824             :    *   time; otherwise, just left it as nullptr.
    1825             :    */
    1826             :   bool Extend3DContext(const nsStyleDisplay* aStyleDisplay,
    1827             :                        mozilla::EffectSet* aEffectSet = nullptr) const;
    1828             :   bool Extend3DContext(mozilla::EffectSet* aEffectSet = nullptr) const {
    1829             :     return Extend3DContext(StyleDisplay(), aEffectSet);
    1830             :   }
    1831             : 
    1832             :   /**
    1833             :    * Returns whether this frame has a parent that Extend3DContext() and has
    1834             :    * its own transform (or hidden backface) to be combined with the parent's
    1835             :    * transform.
    1836             :    *
    1837             :    * @param aStyleDisplay:  If the caller has this->StyleDisplay(), providing
    1838             :    *   it here will improve performance.
    1839             :    */
    1840             :   bool Combines3DTransformWithAncestors(const nsStyleDisplay* aStyleDisplay) const;
    1841           0 :   bool Combines3DTransformWithAncestors() const {
    1842           0 :     return Combines3DTransformWithAncestors(StyleDisplay());
    1843             :   }
    1844             : 
    1845             :   /**
    1846             :    * Returns whether this frame has a hidden backface and has a parent that
    1847             :    * Extend3DContext(). This is useful because in some cases the hidden
    1848             :    * backface can safely be ignored if it could not be visible anyway.
    1849             :    *
    1850             :    */
    1851             :   bool In3DContextAndBackfaceIsHidden() const;
    1852             : 
    1853             :   bool IsPreserve3DLeaf(const nsStyleDisplay* aStyleDisplay,
    1854             :                         mozilla::EffectSet* aEffectSet = nullptr) const {
    1855             :     return Combines3DTransformWithAncestors(aStyleDisplay) &&
    1856             :            !Extend3DContext(aStyleDisplay, aEffectSet);
    1857             :   }
    1858             :   bool IsPreserve3DLeaf(mozilla::EffectSet* aEffectSet = nullptr) const {
    1859             :     return IsPreserve3DLeaf(StyleDisplay(), aEffectSet);
    1860             :   }
    1861             : 
    1862             :   bool HasPerspective(const nsStyleDisplay* aStyleDisplay) const;
    1863             :   bool HasPerspective() const {
    1864             :     return HasPerspective(StyleDisplay());
    1865             :   }
    1866             : 
    1867             :   bool ChildrenHavePerspective(const nsStyleDisplay* aStyleDisplay) const;
    1868             :   bool ChildrenHavePerspective() const {
    1869             :     return ChildrenHavePerspective(StyleDisplay());
    1870             :   }
    1871             : 
    1872             :   /**
    1873             :    * Includes the overflow area of all descendants that participate in the current
    1874             :    * 3d context into aOverflowAreas.
    1875             :    */
    1876             :   void ComputePreserve3DChildrenOverflow(nsOverflowAreas& aOverflowAreas);
    1877             : 
    1878             :   void RecomputePerspectiveChildrenOverflow(const nsIFrame* aStartFrame);
    1879             : 
    1880             :   /**
    1881             :    * Returns the number of ancestors between this and the root of our frame tree
    1882             :    */
    1883             :   uint32_t GetDepthInFrameTree() const;
    1884             : 
    1885             :   /**
    1886             :    * Event handling of GUI events.
    1887             :    *
    1888             :    * @param   aEvent event structure describing the type of event and rge widget
    1889             :    *            where the event originated
    1890             :    *          The |point| member of this is in the coordinate system of the
    1891             :    *          view returned by GetOffsetFromView.
    1892             :    * @param   aEventStatus a return value indicating whether the event was handled
    1893             :    *            and whether default processing should be done
    1894             :    *
    1895             :    * XXX From a frame's perspective it's unclear what the effect of the event status
    1896             :    * is. Does it cause the event to continue propagating through the frame hierarchy
    1897             :    * or is it just returned to the widgets?
    1898             :    *
    1899             :    * @see     WidgetGUIEvent
    1900             :    * @see     nsEventStatus
    1901             :    */
    1902             :   virtual nsresult  HandleEvent(nsPresContext* aPresContext,
    1903             :                                 mozilla::WidgetGUIEvent* aEvent,
    1904             :                                 nsEventStatus* aEventStatus) = 0;
    1905             : 
    1906             :   virtual nsresult  GetContentForEvent(mozilla::WidgetEvent* aEvent,
    1907             :                                        nsIContent** aContent) = 0;
    1908             : 
    1909             :   // This structure keeps track of the content node and offsets associated with
    1910             :   // a point; there is a primary and a secondary offset associated with any
    1911             :   // point.  The primary and secondary offsets differ when the point is over a
    1912             :   // non-text object.  The primary offset is the expected position of the
    1913             :   // cursor calculated from a point; the secondary offset, when it is different,
    1914             :   // indicates that the point is in the boundaries of some selectable object.
    1915             :   // Note that the primary offset can be after the secondary offset; for places
    1916             :   // that need the beginning and end of the object, the StartOffset and
    1917             :   // EndOffset helpers can be used.
    1918             :   struct MOZ_STACK_CLASS ContentOffsets
    1919             :   {
    1920             :     ContentOffsets() : offset(0)
    1921             :                      , secondaryOffset(0)
    1922             :                      , associate(mozilla::CARET_ASSOCIATE_BEFORE) {}
    1923             :     bool IsNull() { return !content; }
    1924             :     // Helpers for places that need the ends of the offsets and expect them in
    1925             :     // numerical order, as opposed to wanting the primary and secondary offsets
    1926             :     int32_t StartOffset() { return std::min(offset, secondaryOffset); }
    1927             :     int32_t EndOffset() { return std::max(offset, secondaryOffset); }
    1928             : 
    1929             :     nsCOMPtr<nsIContent> content;
    1930             :     int32_t offset;
    1931             :     int32_t secondaryOffset;
    1932             :     // This value indicates whether the associated content is before or after
    1933             :     // the offset; the most visible use is to allow the caret to know which line
    1934             :     // to display on.
    1935             :     mozilla::CaretAssociationHint associate;
    1936             :   };
    1937             :   enum {
    1938             :     IGNORE_SELECTION_STYLE = 0x01,
    1939             :     // Treat visibility:hidden frames as non-selectable
    1940             :     SKIP_HIDDEN = 0x02
    1941             :   };
    1942             :   /**
    1943             :    * This function calculates the content offsets for selection relative to
    1944             :    * a point.  Note that this should generally only be callled on the event
    1945             :    * frame associated with an event because this function does not account
    1946             :    * for frame lists other than the primary one.
    1947             :    * @param aPoint point relative to this frame
    1948             :    */
    1949             :   ContentOffsets GetContentOffsetsFromPoint(const nsPoint& aPoint,
    1950             :                                             uint32_t aFlags = 0);
    1951             : 
    1952             :   virtual ContentOffsets GetContentOffsetsFromPointExternal(const nsPoint& aPoint,
    1953             :                                                             uint32_t aFlags = 0)
    1954             :   { return GetContentOffsetsFromPoint(aPoint, aFlags); }
    1955             : 
    1956             :   /**
    1957             :    * Ensure that aImage gets notifed when the underlying image request loads
    1958             :    * or animates.
    1959             :    */
    1960             :   void AssociateImage(const nsStyleImage& aImage, nsPresContext* aPresContext,
    1961             :                       uint32_t aImageLoaderFlags);
    1962             : 
    1963             :   /**
    1964             :    * This structure holds information about a cursor. mContainer represents a
    1965             :    * loaded image that should be preferred. If it is not possible to use it, or
    1966             :    * if it is null, mCursor should be used.
    1967             :    */
    1968             :   struct MOZ_STACK_CLASS Cursor {
    1969             :     nsCOMPtr<imgIContainer> mContainer;
    1970             :     int32_t mCursor = NS_STYLE_CURSOR_AUTO;
    1971             :     bool mHaveHotspot = false;
    1972             :     bool mLoading = false;
    1973             :     float mHotspotX = 0.0f, mHotspotY = 0.0f;
    1974             :   };
    1975             :   /**
    1976             :    * Get the cursor for a given frame.
    1977             :    */
    1978             :   virtual nsresult  GetCursor(const nsPoint&  aPoint,
    1979             :                               Cursor&         aCursor) = 0;
    1980             : 
    1981             :   /**
    1982             :    * Get a point (in the frame's coordinate space) given an offset into
    1983             :    * the content. This point should be on the baseline of text with
    1984             :    * the correct horizontal offset
    1985             :    */
    1986             :   virtual nsresult  GetPointFromOffset(int32_t                  inOffset,
    1987             :                                        nsPoint*                 outPoint) = 0;
    1988             : 
    1989             :   /**
    1990             :    * Get a list of character rects in a given range.
    1991             :    * This is similar version of GetPointFromOffset.
    1992             :    */
    1993             :   virtual nsresult  GetCharacterRectsInRange(int32_t aInOffset,
    1994             :                                              int32_t aLength,
    1995             :                                              nsTArray<nsRect>& aRects) = 0;
    1996             : 
    1997             :   /**
    1998             :    * Get the child frame of this frame which contains the given
    1999             :    * content offset. outChildFrame may be this frame, or nullptr on return.
    2000             :    * outContentOffset returns the content offset relative to the start
    2001             :    * of the returned node. You can also pass a hint which tells the method
    2002             :    * to stick to the end of the first found frame or the beginning of the
    2003             :    * next in case the offset falls on a boundary.
    2004             :    */
    2005             :   virtual nsresult GetChildFrameContainingOffset(int32_t    inContentOffset,
    2006             :                                                  bool       inHint,//false stick left
    2007             :                                                  int32_t*   outFrameContentOffset,
    2008             :                                                  nsIFrame** outChildFrame) = 0;
    2009             : 
    2010             :  /**
    2011             :    * Get the current frame-state value for this frame. aResult is
    2012             :    * filled in with the state bits.
    2013             :    */
    2014             :   nsFrameState GetStateBits() const { return mState; }
    2015             : 
    2016             :   /**
    2017             :    * Update the current frame-state value for this frame.
    2018             :    */
    2019           0 :   void AddStateBits(nsFrameState aBits) { mState |= aBits; }
    2020             :   void RemoveStateBits(nsFrameState aBits) { mState &= ~aBits; }
    2021             :   void AddOrRemoveStateBits(nsFrameState aBits, bool aVal) {
    2022             :     aVal ? AddStateBits(aBits) : RemoveStateBits(aBits);
    2023             :   }
    2024             : 
    2025             :   /**
    2026             :    * Checks if the current frame-state includes all of the listed bits
    2027             :    */
    2028             :   bool HasAllStateBits(nsFrameState aBits) const
    2029             :   {
    2030             :     return (mState & aBits) == aBits;
    2031             :   }
    2032             : 
    2033             :   /**
    2034             :    * Checks if the current frame-state includes any of the listed bits
    2035             :    */
    2036             :   bool HasAnyStateBits(nsFrameState aBits) const
    2037             :   {
    2038             :     return mState & aBits;
    2039             :   }
    2040             : 
    2041             :   /**
    2042             :    * Return true if this frame is the primary frame for mContent.
    2043             :    */
    2044             :   bool IsPrimaryFrame() const { return mIsPrimaryFrame; }
    2045             : 
    2046             :   void SetIsPrimaryFrame(bool aIsPrimary) { mIsPrimaryFrame = aIsPrimary; }
    2047             : 
    2048             :   /**
    2049             :    * This call is invoked on the primary frame for a character data content
    2050             :    * node, when it is changed in the content tree.
    2051             :    */
    2052             :   virtual nsresult  CharacterDataChanged(const CharacterDataChangeInfo&) = 0;
    2053             : 
    2054             :   /**
    2055             :    * This call is invoked when the value of a content objects's attribute
    2056             :    * is changed.
    2057             :    * The first frame that maps that content is asked to deal
    2058             :    * with the change by doing whatever is appropriate.
    2059             :    *
    2060             :    * @param aNameSpaceID the namespace of the attribute
    2061             :    * @param aAttribute the atom name of the attribute
    2062             :    * @param aModType Whether or not the attribute was added, changed, or removed.
    2063             :    *   The constants are defined in MutationEvent.webidl.
    2064             :    */
    2065             :   virtual nsresult  AttributeChanged(int32_t         aNameSpaceID,
    2066             :                                      nsAtom*        aAttribute,
    2067             :                                      int32_t         aModType) = 0;
    2068             : 
    2069             :   /**
    2070             :    * When the content states of a content object change, this method is invoked
    2071             :    * on the primary frame of that content object.
    2072             :    *
    2073             :    * @param aStates the changed states
    2074             :    */
    2075             :   virtual void ContentStatesChanged(mozilla::EventStates aStates);
    2076             : 
    2077             :   /**
    2078             :    * Return how your frame can be split.
    2079             :    */
    2080             :   virtual nsSplittableType GetSplittableType() const = 0;
    2081             : 
    2082             :   /**
    2083             :    * Continuation member functions
    2084             :    */
    2085             :   virtual nsIFrame* GetPrevContinuation() const = 0;
    2086             :   virtual void SetPrevContinuation(nsIFrame*) = 0;
    2087             :   virtual nsIFrame* GetNextContinuation() const = 0;
    2088             :   virtual void SetNextContinuation(nsIFrame*) = 0;
    2089             :   virtual nsIFrame* FirstContinuation() const {
    2090             :     return const_cast<nsIFrame*>(this);
    2091             :   }
    2092             :   virtual nsIFrame* LastContinuation() const {
    2093             :     return const_cast<nsIFrame*>(this);
    2094             :   }
    2095             : 
    2096             :   /**
    2097             :    * GetTailContinuation gets the last non-overflow-container continuation
    2098             :    * in the continuation chain, i.e. where the next sibling element
    2099             :    * should attach).
    2100             :    */
    2101             :   nsIFrame* GetTailContinuation();
    2102             : 
    2103             :   /**
    2104             :    * Flow member functions
    2105             :    */
    2106             :   virtual nsIFrame* GetPrevInFlowVirtual() const = 0;
    2107             :   nsIFrame* GetPrevInFlow() const { return GetPrevInFlowVirtual(); }
    2108             :   virtual void SetPrevInFlow(nsIFrame*) = 0;
    2109             : 
    2110             :   virtual nsIFrame* GetNextInFlowVirtual() const = 0;
    2111             :   nsIFrame* GetNextInFlow() const { return GetNextInFlowVirtual(); }
    2112             :   virtual void SetNextInFlow(nsIFrame*) = 0;
    2113             : 
    2114             :   /**
    2115             :    * Return the first frame in our current flow.
    2116             :    */
    2117             :   virtual nsIFrame* FirstInFlow() const {
    2118             :     return const_cast<nsIFrame*>(this);
    2119             :   }
    2120             : 
    2121             :   /**
    2122             :    * Return the last frame in our current flow.
    2123             :    */
    2124             :   virtual nsIFrame* LastInFlow() const {
    2125             :     return const_cast<nsIFrame*>(this);
    2126             :   }
    2127             : 
    2128             :   /**
    2129             :    * Note: "width" in the names and comments on the following methods
    2130             :    * means inline-size, which could be height in vertical layout
    2131             :    */
    2132             : 
    2133             :   /**
    2134             :    * Mark any stored intrinsic width information as dirty (requiring
    2135             :    * re-calculation).  Note that this should generally not be called
    2136             :    * directly; nsPresShell::FrameNeedsReflow will call it instead.
    2137             :    */
    2138             :   virtual void MarkIntrinsicISizesDirty() = 0;
    2139             : 
    2140             :   /**
    2141             :    * Get the min-content intrinsic inline size of the frame.  This must be
    2142             :    * less than or equal to the max-content intrinsic inline size.
    2143             :    *
    2144             :    * This is *not* affected by the CSS 'min-width', 'width', and
    2145             :    * 'max-width' properties on this frame, but it is affected by the
    2146             :    * values of those properties on this frame's descendants.  (It may be
    2147             :    * called during computation of the values of those properties, so it
    2148             :    * cannot depend on any values in the nsStylePosition for this frame.)
    2149             :    *
    2150             :    * The value returned should **NOT** include the space required for
    2151             :    * padding and border.
    2152             :    *
    2153             :    * Note that many frames will cache the result of this function call
    2154             :    * unless MarkIntrinsicISizesDirty is called.
    2155             :    *
    2156             :    * It is not acceptable for a frame to mark itself dirty when this
    2157             :    * method is called.
    2158             :    *
    2159             :    * This method must not return a negative value.
    2160             :    */
    2161             :   virtual nscoord GetMinISize(gfxContext *aRenderingContext) = 0;
    2162             : 
    2163             :   /**
    2164             :    * Get the max-content intrinsic inline size of the frame.  This must be
    2165             :    * greater than or equal to the min-content intrinsic inline size.
    2166             :    *
    2167             :    * Otherwise, all the comments for |GetMinISize| above apply.
    2168             :    */
    2169             :   virtual nscoord GetPrefISize(gfxContext *aRenderingContext) = 0;
    2170             : 
    2171             :   /**
    2172             :    * |InlineIntrinsicISize| represents the intrinsic width information
    2173             :    * in inline layout.  Code that determines the intrinsic width of a
    2174             :    * region of inline layout accumulates the result into this structure.
    2175             :    * This pattern is needed because we need to maintain state
    2176             :    * information about whitespace (for both collapsing and trimming).
    2177             :    */
    2178             :   struct InlineIntrinsicISizeData {
    2179             :     InlineIntrinsicISizeData()
    2180             :       : mLine(nullptr)
    2181             :       , mLineContainer(nullptr)
    2182             :       , mPrevLines(0)
    2183             :       , mCurrentLine(0)
    2184             :       , mTrailingWhitespace(0)
    2185             :       , mSkipWhitespace(true)
    2186             :     {}
    2187             : 
    2188             :     // The line. This may be null if the inlines are not associated with
    2189             :     // a block or if we just don't know the line.
    2190             :     const nsLineList_iterator* mLine;
    2191             : 
    2192             :     // The line container. Private, to ensure we always use SetLineContainer
    2193             :     // to update it (so that we have a chance to store the mLineContainerWM).
    2194             :     //
    2195             :     // Note that nsContainerFrame::DoInlineIntrinsicISize will clear the
    2196             :     // |mLine| and |mLineContainer| fields when following a next-in-flow link,
    2197             :     // so we must not assume these can always be dereferenced.
    2198             :   private:
    2199             :     nsIFrame* mLineContainer;
    2200             : 
    2201             :     // Setter and getter for the lineContainer field:
    2202             :   public:
    2203             :     void SetLineContainer(nsIFrame* aLineContainer)
    2204             :     {
    2205             :       mLineContainer = aLineContainer;
    2206             :       if (mLineContainer) {
    2207             :         mLineContainerWM = mLineContainer->GetWritingMode();
    2208             :       }
    2209             :     }
    2210             :     nsIFrame* LineContainer() const { return mLineContainer; }
    2211             : 
    2212             :     // The maximum intrinsic width for all previous lines.
    2213             :     nscoord mPrevLines;
    2214             : 
    2215             :     // The maximum intrinsic width for the current line.  At a line
    2216             :     // break (mandatory for preferred width; allowed for minimum width),
    2217             :     // the caller should call |Break()|.
    2218             :     nscoord mCurrentLine;
    2219             : 
    2220             :     // This contains the width of the trimmable whitespace at the end of
    2221             :     // |mCurrentLine|; it is zero if there is no such whitespace.
    2222             :     nscoord mTrailingWhitespace;
    2223             : 
    2224             :     // True if initial collapsable whitespace should be skipped.  This
    2225             :     // should be true at the beginning of a block, after hard breaks
    2226             :     // and when the last text ended with whitespace.
    2227             :     bool mSkipWhitespace;
    2228             : 
    2229             :     // Writing mode of the line container (stored here so that we don't
    2230             :     // lose track of it if the mLineContainer field is reset).
    2231             :     mozilla::WritingMode mLineContainerWM;
    2232             : 
    2233             :     // Floats encountered in the lines.
    2234             :     class FloatInfo {
    2235             :     public:
    2236             :       FloatInfo(const nsIFrame* aFrame, nscoord aWidth)
    2237             :         : mFrame(aFrame), mWidth(aWidth)
    2238             :       { }
    2239             :       const nsIFrame* Frame() const { return mFrame; }
    2240             :       nscoord         Width() const { return mWidth; }
    2241             : 
    2242             :     private:
    2243             :       const nsIFrame* mFrame;
    2244             :       nscoord         mWidth;
    2245             :     };
    2246             : 
    2247             :     nsTArray<FloatInfo> mFloats;
    2248             :   };
    2249             : 
    2250             :   struct InlineMinISizeData : public InlineIntrinsicISizeData {
    2251             :     InlineMinISizeData()
    2252             :       : mAtStartOfLine(true)
    2253             :     {}
    2254             : 
    2255             :     // The default implementation for nsIFrame::AddInlineMinISize.
    2256             :     void DefaultAddInlineMinISize(nsIFrame* aFrame,
    2257             :                                   nscoord   aISize,
    2258             :                                   bool      aAllowBreak = true);
    2259             : 
    2260             :     // We need to distinguish forced and optional breaks for cases where the
    2261             :     // current line total is negative.  When it is, we need to ignore
    2262             :     // optional breaks to prevent min-width from ending up bigger than
    2263             :     // pref-width.
    2264             :     void ForceBreak();
    2265             : 
    2266             :     // If the break here is actually taken, aHyphenWidth must be added to the
    2267             :     // width of the current line.
    2268             :     void OptionallyBreak(nscoord aHyphenWidth = 0);
    2269             : 
    2270             :     // Whether we're currently at the start of the line.  If we are, we
    2271             :     // can't break (for example, between the text-indent and the first
    2272             :     // word).
    2273             :     bool mAtStartOfLine;
    2274             :   };
    2275             : 
    2276             :   struct InlinePrefISizeData : public InlineIntrinsicISizeData {
    2277             :     typedef mozilla::StyleClear StyleClear;
    2278             : 
    2279             :     InlinePrefISizeData()
    2280             :       : mLineIsEmpty(true)
    2281             :     {}
    2282             : 
    2283             :     /**
    2284             :      * Finish the current line and start a new line.
    2285             :      *
    2286             :      * @param aBreakType controls whether isize of floats are considered
    2287             :      * and what floats are kept for the next line:
    2288             :      *  * |None| skips handling floats, which means no floats are
    2289             :      *    removed, and isizes of floats are not considered either.
    2290             :      *  * |Both| takes floats into consideration when computing isize
    2291             :      *    of the current line, and removes all floats after that.
    2292             :      *  * |Left| and |Right| do the same as |Both| except that they only
    2293             :      *    remove floats on the given side, and any floats on the other
    2294             :      *    side that are prior to a float on the given side that has a
    2295             :      *    'clear' property that clears them.
    2296             :      * All other values of StyleClear must be converted to the four
    2297             :      * physical values above for this function.
    2298             :      */
    2299             :     void ForceBreak(StyleClear aBreakType = StyleClear::Both);
    2300             : 
    2301             :     // The default implementation for nsIFrame::AddInlinePrefISize.
    2302             :     void DefaultAddInlinePrefISize(nscoord aISize);
    2303             : 
    2304             :     // True if the current line contains nothing other than placeholders.
    2305             :     bool mLineIsEmpty;
    2306             :   };
    2307             : 
    2308             :   /**
    2309             :    * Add the intrinsic minimum width of a frame in a way suitable for
    2310             :    * use in inline layout to an |InlineIntrinsicISizeData| object that
    2311             :    * represents the intrinsic width information of all the previous
    2312             :    * frames in the inline layout region.
    2313             :    *
    2314             :    * All *allowed* breakpoints within the frame determine what counts as
    2315             :    * a line for the |InlineIntrinsicISizeData|.  This means that
    2316             :    * |aData->mTrailingWhitespace| will always be zero (unlike for
    2317             :    * AddInlinePrefISize).
    2318             :    *
    2319             :    * All the comments for |GetMinISize| apply, except that this function
    2320             :    * is responsible for adding padding, border, and margin and for
    2321             :    * considering the effects of 'width', 'min-width', and 'max-width'.
    2322             :    *
    2323             :    * This may be called on any frame.  Frames that do not participate in
    2324             :    * line breaking can inherit the default implementation on nsFrame,
    2325             :    * which calls |GetMinISize|.
    2326             :    */
    2327             :   virtual void
    2328             :   AddInlineMinISize(gfxContext *aRenderingContext,
    2329             :                     InlineMinISizeData *aData) = 0;
    2330             : 
    2331             :   /**
    2332             :    * Add the intrinsic preferred width of a frame in a way suitable for
    2333             :    * use in inline layout to an |InlineIntrinsicISizeData| object that
    2334             :    * represents the intrinsic width information of all the previous
    2335             :    * frames in the inline layout region.
    2336             :    *
    2337             :    * All the comments for |AddInlineMinISize| and |GetPrefISize| apply,
    2338             :    * except that this fills in an |InlineIntrinsicISizeData| structure
    2339             :    * based on using all *mandatory* breakpoints within the frame.
    2340             :    */
    2341             :   virtual void
    2342             :   AddInlinePrefISize(gfxContext *aRenderingContext,
    2343             :                      InlinePrefISizeData *aData) = 0;
    2344             : 
    2345             :   /**
    2346             :    * Return the horizontal components of padding, border, and margin
    2347             :    * that contribute to the intrinsic width that applies to the parent.
    2348             :    * @param aPercentageBasis the percentage basis to use for padding/margin -
    2349             :    *   i.e. the Containing Block's inline-size
    2350             :    */
    2351             :   struct IntrinsicISizeOffsetData {
    2352             :     nscoord hPadding, hBorder, hMargin;
    2353             : 
    2354             :     IntrinsicISizeOffsetData()
    2355             :       : hPadding(0), hBorder(0), hMargin(0)
    2356             :     {}
    2357             :   };
    2358             :   virtual IntrinsicISizeOffsetData
    2359             :   IntrinsicISizeOffsets(nscoord aPercentageBasis = NS_UNCONSTRAINEDSIZE) = 0;
    2360             : 
    2361             :   /**
    2362             :    * Return the bsize components of padding, border, and margin
    2363             :    * that contribute to the intrinsic width that applies to the parent.
    2364             :    * @param aPercentageBasis the percentage basis to use for padding/margin -
    2365             :    *   i.e. the Containing Block's inline-size
    2366             :    */
    2367             :   IntrinsicISizeOffsetData
    2368             :   IntrinsicBSizeOffsets(nscoord aPercentageBasis = NS_UNCONSTRAINEDSIZE);
    2369             : 
    2370             :   virtual mozilla::IntrinsicSize GetIntrinsicSize() = 0;
    2371             : 
    2372             :   /**
    2373             :    * Get the intrinsic ratio of this element, or nsSize(0,0) if it has
    2374             :    * no intrinsic ratio.  The intrinsic ratio is the ratio of the
    2375             :    * height/width of a box with an intrinsic size or the intrinsic
    2376             :    * aspect ratio of a scalable vector image without an intrinsic size.
    2377             :    *
    2378             :    * Either one of the sides may be zero, indicating a zero or infinite
    2379             :    * ratio.
    2380             :    */
    2381             :   virtual nsSize GetIntrinsicRatio() = 0;
    2382             : 
    2383             :   /**
    2384             :    * Bit-flags to pass to ComputeSize in |aFlags| parameter.
    2385             :    */
    2386             :   enum ComputeSizeFlags {
    2387             :     eDefault =           0,
    2388             :     /**
    2389             :      * Set if the frame is in a context where non-replaced blocks should
    2390             :      * shrink-wrap (e.g., it's floating, absolutely positioned, or
    2391             :      * inline-block).
    2392             :      */
    2393             :     eShrinkWrap =        1 << 0,
    2394             :     /**
    2395             :      * Set if we'd like to compute our 'auto' bsize, regardless of our actual
    2396             :      * corresponding computed value. (e.g. to get an intrinsic height for flex
    2397             :      * items with "min-height: auto" to use during flexbox layout.)
    2398             :      */
    2399             :     eUseAutoBSize =      1 << 1,
    2400             :     /**
    2401             :      * Indicates that we should clamp the margin-box min-size to the given CB
    2402             :      * size.  This is used for implementing the grid area clamping here:
    2403             :      * https://drafts.csswg.org/css-grid/#min-size-auto
    2404             :      */
    2405             :     eIClampMarginBoxMinSize = 1 << 2, // clamp in our inline axis
    2406             :     eBClampMarginBoxMinSize = 1 << 3, // clamp in our block axis
    2407             :     /**
    2408             :      * The frame is stretching (per CSS Box Alignment) and doesn't have an
    2409             :      * Automatic Minimum Size in the indicated axis.
    2410             :      * (may be used for both flex/grid items, but currently only used for Grid)
    2411             :      * https://drafts.csswg.org/css-grid/#min-size-auto
    2412             :      * https://drafts.csswg.org/css-align-3/#valdef-justify-self-stretch
    2413             :      */
    2414             :     eIApplyAutoMinSize = 1 << 4, // only has an effect when eShrinkWrap is false
    2415             :   };
    2416             : 
    2417             :   /**
    2418             :    * Compute the size that a frame will occupy.  Called while
    2419             :    * constructing the ReflowInput to be used to Reflow the frame,
    2420             :    * in order to fill its mComputedWidth and mComputedHeight member
    2421             :    * variables.
    2422             :    *
    2423             :    * The |height| member of the return value may be
    2424             :    * NS_UNCONSTRAINEDSIZE, but the |width| member must not be.
    2425             :    *
    2426             :    * Note that the reason that border and padding need to be passed
    2427             :    * separately is so that the 'box-sizing' property can be handled.
    2428             :    * Thus aMargin includes absolute positioning offsets as well.
    2429             :    *
    2430             :    * @param aWritingMode  The writing mode to use for the returned size
    2431             :    *                      (need not match this frame's writing mode).
    2432             :    *                      This is also the writing mode of the passed-in
    2433             :    *                      LogicalSize parameters.
    2434             :    * @param aCBSize  The size of the element's containing block.  (Well,
    2435             :    *                 the |height| component isn't really.)
    2436             :    * @param aAvailableWidth  The available width for 'auto' widths.
    2437             :    *                         This is usually the same as aCBSize.width,
    2438             :    *                         but differs in cases such as block
    2439             :    *                         formatting context roots next to floats, or
    2440             :    *                         in some cases of float reflow in quirks
    2441             :    *                         mode.
    2442             :    * @param aMargin  The sum of the vertical / horizontal margins
    2443             :    *                 ***AND*** absolute positioning offsets (top, right,
    2444             :    *                 bottom, left) of the frame, including actual values
    2445             :    *                 resulting from percentages and from the
    2446             :    *                 "hypothetical box" for absolute positioning, but
    2447             :    *                 not including actual values resulting from 'auto'
    2448             :    *                 margins or ignored 'auto' values in absolute
    2449             :    *                 positioning.
    2450             :    * @param aBorder  The sum of the vertical / horizontal border widths
    2451             :    *                 of the frame.
    2452             :    * @param aPadding The sum of the vertical / horizontal margins of
    2453             :    *                 the frame, including actual values resulting from
    2454             :    *                 percentages.
    2455             :    * @param aFlags   Flags to further customize behavior (definitions above).
    2456             :    */
    2457             :   virtual mozilla::LogicalSize
    2458             :   ComputeSize(gfxContext *aRenderingContext,
    2459             :               mozilla::WritingMode aWritingMode,
    2460             :               const mozilla::LogicalSize& aCBSize,
    2461             :               nscoord aAvailableISize,
    2462             :               const mozilla::LogicalSize& aMargin,
    2463             :               const mozilla::LogicalSize& aBorder,
    2464             :               const mozilla::LogicalSize& aPadding,
    2465             :               ComputeSizeFlags aFlags) = 0;
    2466             : 
    2467             :   /**
    2468             :    * Compute a tight bounding rectangle for the frame. This is a rectangle
    2469             :    * that encloses the pixels that are actually drawn. We're allowed to be
    2470             :    * conservative and currently we don't try very hard. The rectangle is
    2471             :    * in appunits and relative to the origin of this frame.
    2472             :    *
    2473             :    * This probably only needs to include frame bounds, glyph bounds, and
    2474             :    * text decorations, but today it sometimes includes other things that
    2475             :    * contribute to visual overflow.
    2476             :    *
    2477             :    * @param aDrawTarget a draw target that can be used if we need
    2478             :    * to do measurement
    2479             :    */
    2480             :   virtual nsRect ComputeTightBounds(DrawTarget* aDrawTarget) const;
    2481             : 
    2482             :   /**
    2483             :    * This function is similar to GetPrefISize and ComputeTightBounds: it
    2484             :    * computes the left and right coordinates of a preferred tight bounding
    2485             :    * rectangle for the frame. This is a rectangle that would enclose the pixels
    2486             :    * that are drawn if we lay out the element without taking any optional line
    2487             :    * breaks. The rectangle is in appunits and relative to the origin of this
    2488             :    * frame. Currently, this function is only implemented for nsBlockFrame and
    2489             :    * nsTextFrame and is used to determine intrinsic widths of MathML token
    2490             :    * elements.
    2491             : 
    2492             :    * @param aContext a rendering context that can be used if we need
    2493             :    * to do measurement
    2494             :    * @param aX      computed left coordinate of the tight bounding rectangle
    2495             :    * @param aXMost  computed intrinsic width of the tight bounding rectangle
    2496             :    *
    2497             :    */
    2498             :   virtual nsresult GetPrefWidthTightBounds(gfxContext* aContext,
    2499             :                                            nscoord* aX,
    2500             :                                            nscoord* aXMost);
    2501             : 
    2502             :   /**
    2503             :    * The frame is given an available size and asked for its desired
    2504             :    * size.  This is the frame's opportunity to reflow its children.
    2505             :    *
    2506             :    * If the frame has the NS_FRAME_IS_DIRTY bit set then it is
    2507             :    * responsible for completely reflowing itself and all of its
    2508             :    * descendants.
    2509             :    *
    2510             :    * Otherwise, if the frame has the NS_FRAME_HAS_DIRTY_CHILDREN bit
    2511             :    * set, then it is responsible for reflowing at least those
    2512             :    * children that have NS_FRAME_HAS_DIRTY_CHILDREN or NS_FRAME_IS_DIRTY
    2513             :    * set.
    2514             :    *
    2515             :    * If a difference in available size from the previous reflow causes
    2516             :    * the frame's size to change, it should reflow descendants as needed.
    2517             :    *
    2518             :    * @param aReflowOutput <i>out</i> parameter where you should return the
    2519             :    *          desired size and ascent/descent info. You should include any
    2520             :    *          space you want for border/padding in the desired size you return.
    2521             :    *
    2522             :    *          It's okay to return a desired size that exceeds the avail
    2523             :    *          size if that's the smallest you can be, i.e. it's your
    2524             :    *          minimum size.
    2525             :    *
    2526             :    *          For an incremental reflow you are responsible for invalidating
    2527             :    *          any area within your frame that needs repainting (including
    2528             :    *          borders). If your new desired size is different than your current
    2529             :    *          size, then your parent frame is responsible for making sure that
    2530             :    *          the difference between the two rects is repainted
    2531             :    *
    2532             :    * @param aReflowInput information about your reflow including the reason
    2533             :    *          for the reflow and the available space in which to lay out. Each
    2534             :    *          dimension of the available space can either be constrained or
    2535             :    *          unconstrained (a value of NS_UNCONSTRAINEDSIZE).
    2536             :    *
    2537             :    *          Note that the available space can be negative. In this case you
    2538             :    *          still must return an accurate desired size. If you're a container
    2539             :    *          you must <b>always</b> reflow at least one frame regardless of the
    2540             :    *          available space
    2541             :    *
    2542             :    * @param aStatus a return value indicating whether the frame is complete
    2543             :    *          and whether the next-in-flow is dirty and needs to be reflowed
    2544             :    */
    2545             :   virtual void Reflow(nsPresContext*           aPresContext,
    2546             :                       ReflowOutput&     aReflowOutput,
    2547             :                       const ReflowInput& aReflowInput,
    2548             :                       nsReflowStatus&          aStatus) = 0;
    2549             : 
    2550             :   /**
    2551             :    * Post-reflow hook. After a frame is reflowed this method will be called
    2552             :    * informing the frame that this reflow process is complete, and telling the
    2553             :    * frame the status returned by the Reflow member function.
    2554             :    *
    2555             :    * This call may be invoked many times, while NS_FRAME_IN_REFLOW is set, before
    2556             :    * it is finally called once with a NS_FRAME_REFLOW_COMPLETE value. When called
    2557             :    * with a NS_FRAME_REFLOW_COMPLETE value the NS_FRAME_IN_REFLOW bit in the
    2558             :    * frame state will be cleared.
    2559             :    *
    2560             :    * XXX This doesn't make sense. If the frame is reflowed but not complete, then
    2561             :    * the status should have IsIncomplete() equal to true.
    2562             :    * XXX Don't we want the semantics to dictate that we only call this once for
    2563             :    * a given reflow?
    2564             :    */
    2565             :   virtual void DidReflow(nsPresContext*           aPresContext,
    2566             :                          const ReflowInput* aReflowInput) = 0;
    2567             : 
    2568             :   /**
    2569             :    * Updates the overflow areas of the frame. This can be called if an
    2570             :    * overflow area of the frame's children has changed without reflowing.
    2571             :    * @return true if either of the overflow areas for this frame have changed.
    2572             :    */
    2573             :   bool UpdateOverflow();
    2574             : 
    2575             :   /**
    2576             :    * Computes any overflow area created by the frame itself (outside of the
    2577             :    * frame bounds) and includes it into aOverflowAreas.
    2578             :    *
    2579             :    * Returns false if updating overflow isn't supported for this frame.
    2580             :    * If the frame requires a reflow instead, then it is responsible
    2581             :    * for scheduling one.
    2582             :    */
    2583             :   virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) = 0;
    2584             : 
    2585             :   /**
    2586             :    * Computes any overflow area created by children of this frame and
    2587             :    * includes it into aOverflowAreas.
    2588             :    */
    2589             :   virtual void UnionChildOverflow(nsOverflowAreas& aOverflowAreas) = 0;
    2590             : 
    2591             :   /**
    2592             :    * Helper method used by block reflow to identify runs of text so
    2593             :    * that proper word-breaking can be done.
    2594             :    *
    2595             :    * @return
    2596             :    *    true if we can continue a "text run" through the frame. A
    2597             :    *    text run is text that should be treated contiguously for line
    2598             :    *    and word breaking.
    2599             :    */
    2600             :   virtual bool CanContinueTextRun() const = 0;
    2601             : 
    2602             :   /**
    2603             :    * Computes an approximation of the rendered text of the frame and its
    2604             :    * continuations. Returns nothing for non-text frames.
    2605             :    * The appended text will often not contain all the whitespace from source,
    2606             :    * depending on CSS white-space processing.
    2607             :    * if aEndOffset goes past end, use the text up to the string's end.
    2608             :    * Call this on the primary frame for a text node.
    2609             :    * aStartOffset and aEndOffset can be content offsets or offsets in the
    2610             :    * rendered text, depending on aOffsetType.
    2611             :    * Returns a string, as well as offsets identifying the start of the text
    2612             :    * within the rendered text for the whole node, and within the text content
    2613             :    * of the node.
    2614             :    */
    2615             :   struct RenderedText {
    2616             :     nsAutoString mString;
    2617             :     uint32_t mOffsetWithinNodeRenderedText;
    2618             :     int32_t mOffsetWithinNodeText;
    2619             :     RenderedText() : mOffsetWithinNodeRenderedText(0),
    2620             :         mOffsetWithinNodeText(0) {}
    2621             :   };
    2622             :   enum class TextOffsetType {
    2623             :     // Passed-in start and end offsets are within the content text.
    2624             :     OFFSETS_IN_CONTENT_TEXT,
    2625             :     // Passed-in start and end offsets are within the rendered text.
    2626             :     OFFSETS_IN_RENDERED_TEXT
    2627             :   };
    2628             :   enum class TrailingWhitespace {
    2629             :     TRIM_TRAILING_WHITESPACE,
    2630             :     // Spaces preceding a caret at the end of a line should not be trimmed
    2631             :     DONT_TRIM_TRAILING_WHITESPACE
    2632             :   };
    2633             :   virtual RenderedText GetRenderedText(uint32_t aStartOffset = 0,
    2634             :                                        uint32_t aEndOffset = UINT32_MAX,
    2635             :                                        TextOffsetType aOffsetType =
    2636             :                                            TextOffsetType::OFFSETS_IN_CONTENT_TEXT,
    2637             :                                        TrailingWhitespace aTrimTrailingWhitespace =
    2638             :                                            TrailingWhitespace::TRIM_TRAILING_WHITESPACE)
    2639             :   { return RenderedText(); }
    2640             : 
    2641             :   /**
    2642             :    * Returns true if the frame contains any non-collapsed characters.
    2643             :    * This method is only available for text frames, and it will return false
    2644             :    * for all other frame types.
    2645             :    */
    2646             :   virtual bool HasAnyNoncollapsedCharacters()
    2647             :   { return false; }
    2648             : 
    2649             :   /**
    2650             :    * Returns true if events of the given type targeted at this frame
    2651             :    * should only be dispatched to the system group.
    2652             :    */
    2653             :   virtual bool OnlySystemGroupDispatch(mozilla::EventMessage aMessage) const
    2654             :   { return false; }
    2655             : 
    2656             :   //
    2657             :   // Accessor functions to an associated view object:
    2658             :   //
    2659           0 :   bool HasView() const { return !!(mState & NS_FRAME_HAS_VIEW); }
    2660             : protected:
    2661           0 :   virtual nsView* GetViewInternal() const
    2662             :   {
    2663           0 :     MOZ_ASSERT_UNREACHABLE("method should have been overridden by subclass");
    2664             :     return nullptr;
    2665             :   }
    2666             :   virtual void SetViewInternal(nsView* aView)
    2667             :   {
    2668             :     MOZ_ASSERT_UNREACHABLE("method should have been overridden by subclass");
    2669             :   }
    2670             : public:
    2671           0 :   nsView* GetView() const
    2672             :   {
    2673           0 :     if (MOZ_LIKELY(!HasView())) {
    2674             :       return nullptr;
    2675             :     }
    2676           2 :     nsView* view = GetViewInternal();
    2677           0 :     MOZ_ASSERT(view, "GetViewInternal() should agree with HasView()");
    2678             :     return view;
    2679             :   }
    2680             :   void SetView(nsView* aView);
    2681             : 
    2682             :   /**
    2683             :    * Find the closest view (on |this| or an ancestor).
    2684             :    * If aOffset is non-null, it will be set to the offset of |this|
    2685             :    * from the returned view.
    2686             :    */
    2687             :   nsView* GetClosestView(nsPoint* aOffset = nullptr) const;
    2688             : 
    2689             :   /**
    2690             :    * Find the closest ancestor (excluding |this| !) that has a view
    2691             :    */
    2692             :   nsIFrame* GetAncestorWithView() const;
    2693             : 
    2694             :   /**
    2695             :    * Sets the view's attributes from the frame style.
    2696             :    * Call this for nsChangeHint_SyncFrameView style changes or when the view
    2697             :    * has just been created.
    2698             :    * @param aView the frame's view or use GetView() if nullptr is given
    2699             :    */
    2700             :   void SyncFrameViewProperties(nsView* aView = nullptr);
    2701             : 
    2702             :   /**
    2703             :    * Get the offset between the coordinate systems of |this| and aOther.
    2704             :    * Adding the return value to a point in the coordinate system of |this|
    2705             :    * will transform the point to the coordinate system of aOther.
    2706             :    *
    2707             :    * aOther must be non-null.
    2708             :    *
    2709             :    * This function is fastest when aOther is an ancestor of |this|.
    2710             :    *
    2711             :    * This function _DOES NOT_ work across document boundaries.
    2712             :    * Use this function only when |this| and aOther are in the same document.
    2713             :    *
    2714             :    * NOTE: this actually returns the offset from aOther to |this|, but
    2715             :    * that offset is added to transform _coordinates_ from |this| to
    2716             :    * aOther.
    2717             :    */
    2718             :   nsPoint GetOffsetTo(const nsIFrame* aOther) const;
    2719             : 
    2720             :   /**
    2721             :    * Just like GetOffsetTo, but treats all scrollframes as scrolled to
    2722             :    * their origin.
    2723             :    */
    2724             :   nsPoint GetOffsetToIgnoringScrolling(const nsIFrame* aOther) const;
    2725             : 
    2726             :   /**
    2727             :    * Get the offset between the coordinate systems of |this| and aOther
    2728             :    * expressed in appunits per dev pixel of |this|' document. Adding the return
    2729             :    * value to a point that is relative to the origin of |this| will make the
    2730             :    * point relative to the origin of aOther but in the appunits per dev pixel
    2731             :    * ratio of |this|.
    2732             :    *
    2733             :    * aOther must be non-null.
    2734             :    *
    2735             :    * This function is fastest when aOther is an ancestor of |this|.
    2736             :    *
    2737             :    * This function works across document boundaries.
    2738             :    *
    2739             :    * Because this function may cross document boundaries that have different
    2740             :    * app units per dev pixel ratios it needs to be used very carefully.
    2741             :    *
    2742             :    * NOTE: this actually returns the offset from aOther to |this|, but
    2743             :    * that offset is added to transform _coordinates_ from |this| to
    2744             :    * aOther.
    2745             :    */
    2746             :   nsPoint GetOffsetToCrossDoc(const nsIFrame* aOther) const;
    2747             : 
    2748             :   /**
    2749             :    * Like GetOffsetToCrossDoc, but the caller can specify which appunits
    2750             :    * to return the result in.
    2751             :    */
    2752             :   nsPoint GetOffsetToCrossDoc(const nsIFrame* aOther, const int32_t aAPD) const;
    2753             : 
    2754             :   /**
    2755             :    * Get the rect of the frame relative to the top-left corner of the
    2756             :    * screen in CSS pixels.
    2757             :    * @return the CSS pixel rect of the frame relative to the top-left
    2758             :    *         corner of the screen.
    2759             :    */
    2760             :   mozilla::CSSIntRect GetScreenRect() const;
    2761             : 
    2762             :   /**
    2763             :    * Get the screen rect of the frame in app units.
    2764             :    * @return the app unit rect of the frame in screen coordinates.
    2765             :    */
    2766             :   nsRect GetScreenRectInAppUnits() const;
    2767             : 
    2768             :   /**
    2769             :    * Returns the offset from this frame to the closest geometric parent that
    2770             :    * has a view. Also returns the containing view or null in case of error
    2771             :    */
    2772             :   void GetOffsetFromView(nsPoint& aOffset, nsView** aView) const;
    2773             : 
    2774             :   /**
    2775             :    * Returns the nearest widget containing this frame. If this frame has a
    2776             :    * view and the view has a widget, then this frame's widget is
    2777             :    * returned, otherwise this frame's geometric parent is checked
    2778             :    * recursively upwards.
    2779             :    */
    2780             :   nsIWidget* GetNearestWidget() const;
    2781             : 
    2782             :   /**
    2783             :    * Same as GetNearestWidget() above but uses an outparam to return the offset
    2784             :    * of this frame to the returned widget expressed in appunits of |this| (the
    2785             :    * widget might be in a different document with a different zoom).
    2786             :    */
    2787             :   nsIWidget* GetNearestWidget(nsPoint& aOffset) const;
    2788             : 
    2789             :   /**
    2790             :    * Whether the content for this frame is disabled, used for event handling.
    2791             :    */
    2792             :   bool IsContentDisabled() const;
    2793             : 
    2794             :   /**
    2795             :    * Get the "type" of the frame.
    2796             :    *
    2797             :    * @see mozilla::LayoutFrameType
    2798             :    */
    2799           0 :   mozilla::LayoutFrameType Type() const {
    2800           0 :     MOZ_ASSERT(uint8_t(mClass) < mozilla::ArrayLength(sLayoutFrameTypes));
    2801           0 :     return sLayoutFrameTypes[uint8_t(mClass)];
    2802             :   }
    2803             : 
    2804             : #define FRAME_TYPE(name_)                                                      \
    2805             :   bool Is##name_##Frame() const                                                \
    2806             :   {                                                                            \
    2807             :     return Type() == mozilla::LayoutFrameType::name_;                          \
    2808             :   }
    2809             : #include "mozilla/FrameTypeList.h"
    2810             : #undef FRAME_TYPE
    2811             : 
    2812             :   /**
    2813             :    * Returns a transformation matrix that converts points in this frame's
    2814             :    * coordinate space to points in some ancestor frame's coordinate space.
    2815             :    * The frame decides which ancestor it will use as a reference point.
    2816             :    * If this frame has no ancestor, aOutAncestor will be set to null.
    2817             :    *
    2818             :    * @param aStopAtAncestor don't look further than aStopAtAncestor. If null,
    2819             :    *   all ancestors (including across documents) will be traversed.
    2820             :    * @param aOutAncestor [out] The ancestor frame the frame has chosen.  If
    2821             :    *   this frame has no ancestor, *aOutAncestor will be set to null. If
    2822             :    * this frame is not a root frame, then *aOutAncestor will be in the same
    2823             :    * document as this frame. If this frame IsTransformed(), then *aOutAncestor
    2824             :    * will be the parent frame (if not preserve-3d) or the nearest non-transformed
    2825             :    * ancestor (if preserve-3d).
    2826             :    * @return A Matrix4x4 that converts points in this frame's coordinate space
    2827             :    *   into points in aOutAncestor's coordinate space.
    2828             :    */
    2829             :   enum {
    2830             :     IN_CSS_UNITS = 1 << 0,
    2831             :     STOP_AT_STACKING_CONTEXT_AND_DISPLAY_PORT = 1 << 1
    2832             :   };
    2833             :   Matrix4x4Flagged GetTransformMatrix(const nsIFrame* aStopAtAncestor,
    2834             :                                       nsIFrame **aOutAncestor,
    2835             :                                       uint32_t aFlags = 0);
    2836             : 
    2837             :   /**
    2838             :    * Bit-flags to pass to IsFrameOfType()
    2839             :    */
    2840             :   enum {
    2841             :     eMathML =                           1 << 0,
    2842             :     eSVG =                              1 << 1,
    2843             :     eSVGForeignObject =                 1 << 2,
    2844             :     eSVGContainer =                     1 << 3,
    2845             :     eSVGGeometry =                      1 << 4,
    2846             :     eSVGPaintServer =                   1 << 5,
    2847             :     eBidiInlineContainer =              1 << 6,
    2848             :     // the frame is for a replaced element, such as an image
    2849             :     eReplaced =                         1 << 7,
    2850             :     // Frame that contains a block but looks like a replaced element
    2851             :     // from the outside
    2852             :     eReplacedContainsBlock =            1 << 8,
    2853             :     // A frame that participates in inline reflow, i.e., one that
    2854             :     // requires ReflowInput::mLineLayout.
    2855             :     eLineParticipant =                  1 << 9,
    2856             :     eXULBox =                           1 << 10,
    2857             :     eCanContainOverflowContainers =     1 << 11,
    2858             :     eBlockFrame =                       1 << 12,
    2859             :     eTablePart =                        1 << 13,
    2860             :     // If this bit is set, the frame doesn't allow ignorable whitespace as
    2861             :     // children. For example, the whitespace between <table>\n<tr>\n<td>
    2862             :     // will be excluded during the construction of children.
    2863             :     eExcludesIgnorableWhitespace =      1 << 14,
    2864             :     eSupportsCSSTransforms =            1 << 15,
    2865             : 
    2866             :     // A replaced element that has replaced-element sizing
    2867             :     // characteristics (i.e., like images or iframes), as opposed to
    2868             :     // inline-block sizing characteristics (like form controls).
    2869             :     eReplacedSizing =                   1 << 16,
    2870             : 
    2871             :     // These are to allow nsFrame::Init to assert that IsFrameOfType
    2872             :     // implementations all call the base class method.  They are only
    2873             :     // meaningful in DEBUG builds.
    2874             :     eDEBUGAllFrames =                   1 << 30,
    2875             :     eDEBUGNoFrames =                    1 << 31
    2876             :   };
    2877             : 
    2878             :   /**
    2879             :    * API for doing a quick check if a frame is of a given
    2880             :    * type. Returns true if the frame matches ALL flags passed in.
    2881             :    *
    2882             :    * Implementations should always override with inline virtual
    2883             :    * functions that call the base class's IsFrameOfType method.
    2884             :    */
    2885             :   virtual bool IsFrameOfType(uint32_t aFlags) const
    2886             :   {
    2887             : #ifdef DEBUG
    2888             :     return !(aFlags & ~(nsIFrame::eDEBUGAllFrames | nsIFrame::eSupportsCSSTransforms));
    2889             : #else
    2890             :     return !(aFlags & ~nsIFrame::eSupportsCSSTransforms);
    2891             : #endif
    2892             :   }
    2893             : 
    2894             :   /**
    2895             :    * Returns true if the frame is a block wrapper.
    2896             :    */
    2897             :   bool IsBlockWrapper() const;
    2898             : 
    2899             :   /**
    2900             :    * Get this frame's CSS containing block.
    2901             :    *
    2902             :    * The algorithm is defined in
    2903             :    * http://www.w3.org/TR/CSS2/visudet.html#containing-block-details.
    2904             :    *
    2905             :    * NOTE: This is guaranteed to return a non-null pointer when invoked on any
    2906             :    * frame other than the root frame.
    2907             :    *
    2908             :    * Requires SKIP_SCROLLED_FRAME to get behaviour matching the spec, otherwise
    2909             :    * it can return anonymous inner scrolled frames. Bug 1204044 is filed for
    2910             :    * investigating whether any of the callers actually require the default
    2911             :    * behaviour.
    2912             :    */
    2913             :   enum {
    2914             :     // If the containing block is an anonymous scrolled frame, then skip over
    2915             :     // this and return the outer scroll frame.
    2916             :     SKIP_SCROLLED_FRAME = 0x01
    2917             :   };
    2918             :   nsIFrame* GetContainingBlock(uint32_t aFlags,
    2919             :                                const nsStyleDisplay* aStyleDisplay) const;
    2920             :   nsIFrame* GetContainingBlock(uint32_t aFlags = 0) const {
    2921             :     return GetContainingBlock(aFlags, StyleDisplay());
    2922             :   }
    2923             : 
    2924             :   /**
    2925             :    * Is this frame a containing block for floating elements?
    2926             :    * Note that very few frames are, so default to false.
    2927             :    */
    2928             :   virtual bool IsFloatContainingBlock() const { return false; }
    2929             : 
    2930             :   /**
    2931             :    * Is this a leaf frame?  Frames that want the frame constructor to be able
    2932             :    * to construct kids for them should return false, all others should return
    2933             :    * true.  Note that returning true here does not mean that the frame _can't_
    2934             :    * have kids.  It could still have kids created via
    2935             :    * nsIAnonymousContentCreator.  Returning true indicates that "normal"
    2936             :    * (non-anonymous, XBL-bound, CSS generated content, etc) children should not
    2937             :    * be constructed.
    2938             :    */
    2939             :   bool IsLeaf() const
    2940             :   {
    2941             :     MOZ_ASSERT(uint8_t(mClass) < mozilla::ArrayLength(sFrameClassBits));
    2942             :     FrameClassBits bits = sFrameClassBits[uint8_t(mClass)];
    2943             :     if (MOZ_UNLIKELY(bits & eFrameClassBitsDynamicLeaf)) {
    2944             :       return IsLeafDynamic();
    2945             :     }
    2946             :     return bits & eFrameClassBitsLeaf;
    2947             :   }
    2948             : 
    2949             :   /**
    2950             :    * Marks all display items created by this frame as needing a repaint,
    2951             :    * and calls SchedulePaint() if requested and one is not already pending.
    2952             :    *
    2953             :    * This includes all display items created by this frame, including
    2954             :    * container types.
    2955             :    *
    2956             :    * @param aDisplayItemKey If specified, only issues an invalidate
    2957             :    * if this frame painted a display item of that type during the
    2958             :    * previous paint. SVG rendering observers are always notified.
    2959             :    * @param aRebuildDisplayItems If true, then adds this frame to the
    2960             :    * list of modified frames for display list building. Only pass false
    2961             :    * if you're sure that the relevant display items will be rebuilt
    2962             :    * already (possibly by an ancestor being in the modified list).
    2963             :    */
    2964             :   virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0, bool aRebuildDisplayItems = true);
    2965             : 
    2966             :   /**
    2967             :    * Same as InvalidateFrame(), but only mark a fixed rect as needing
    2968             :    * repainting.
    2969             :    *
    2970             :    * @param aRect The rect to invalidate, relative to the TopLeft of the
    2971             :    * frame's border box.
    2972             :    * @param aDisplayItemKey If specified, only issues an invalidate
    2973             :    * if this frame painted a display item of that type during the
    2974             :    * previous paint. SVG rendering observers are always notified.
    2975             :    * @param aRebuildDisplayItems If true, then adds this frame to the
    2976             :    * list of modified frames for display list building. Only pass false
    2977             :    * if you're sure that the relevant display items will be rebuilt
    2978             :    * already (possibly by an ancestor being in the modified list).
    2979             :    */
    2980             :   virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0, bool aRebuildDisplayItems = true);
    2981             : 
    2982             :   /**
    2983             :    * Calls InvalidateFrame() on all frames descendant frames (including
    2984             :    * this one).
    2985             :    *
    2986             :    * This function doesn't walk through placeholder frames to invalidate
    2987             :    * the out-of-flow frames.
    2988             :    *
    2989             :    * @param aRebuildDisplayItems If true, then adds this frame to the
    2990             :    * list of modified frames for display list building. Only pass false
    2991             :    * if you're sure that the relevant display items will be rebuilt
    2992             :    * already (possibly by an ancestor being in the modified list).
    2993             :    */
    2994             :   void InvalidateFrameSubtree(bool aRebuildDisplayItems = true);
    2995             : 
    2996             :   /**
    2997             :    * Called when a frame is about to be removed and needs to be invalidated.
    2998             :    * Normally does nothing since DLBI handles removed frames.
    2999             :    */
    3000             :   virtual void InvalidateFrameForRemoval() {}
    3001             : 
    3002             :   /**
    3003             :    * When HasUserData(frame->LayerIsPrerenderedDataKey()), then the
    3004             :    * entire overflow area of this frame has been rendered in its
    3005             :    * layer(s).
    3006             :    */
    3007             :   static void* LayerIsPrerenderedDataKey() {
    3008             :     return &sLayerIsPrerenderedDataKey;
    3009             :   }
    3010             :   static uint8_t sLayerIsPrerenderedDataKey;
    3011             : 
    3012             :    /**
    3013             :    * Try to update this frame's transform without invalidating any
    3014             :    * content.  Return true iff successful.  If unsuccessful, the
    3015             :    * caller is responsible for scheduling an invalidating paint.
    3016             :    *
    3017             :    * If the result is true, aLayerResult will be filled in with the
    3018             :    * transform layer for the frame.
    3019             :    */
    3020             :   bool TryUpdateTransformOnly(Layer** aLayerResult);
    3021             : 
    3022             :   /**
    3023             :    * Checks if a frame has had InvalidateFrame() called on it since the
    3024             :    * last paint.
    3025             :    *
    3026             :    * If true, then the invalid rect is returned in aRect, with an
    3027             :    * empty rect meaning all pixels drawn by this frame should be
    3028             :    * invalidated.
    3029             :    * If false, aRect is left unchanged.
    3030             :    */
    3031             :   bool IsInvalid(nsRect& aRect);
    3032             : 
    3033             :   /**
    3034             :    * Check if any frame within the frame subtree (including this frame)
    3035             :    * returns true for IsInvalid().
    3036             :    */
    3037             :   bool HasInvalidFrameInSubtree()
    3038             :   {
    3039             :     return HasAnyStateBits(NS_FRAME_NEEDS_PAINT | NS_FRAME_DESCENDANT_NEEDS_PAINT);
    3040             :   }
    3041             : 
    3042             :   /**
    3043             :    * Removes the invalid state from the current frame and all
    3044             :    * descendant frames.
    3045             :    */
    3046             :   void ClearInvalidationStateBits();
    3047             : 
    3048             :   /**
    3049             :    * Ensures that the refresh driver is running, and schedules a view
    3050             :    * manager flush on the next tick.
    3051             :    *
    3052             :    * The view manager flush will update the layer tree, repaint any
    3053             :    * invalid areas in the layer tree and schedule a layer tree
    3054             :    * composite operation to display the layer tree.
    3055             :    *
    3056             :    * In general it is not necessary for frames to call this when they change.
    3057             :    * For example, changes that result in a reflow will have this called for
    3058             :    * them by PresContext::DoReflow when the reflow begins. Style changes that
    3059             :    * do not trigger a reflow should have this called for them by
    3060             :    * DoApplyRenderingChangeToTree.
    3061             :    *
    3062             :    * @param aType PAINT_COMPOSITE_ONLY : No changes have been made
    3063             :    * that require a layer tree update, so only schedule a layer
    3064             :    * tree composite.
    3065             :    * PAINT_DELAYED_COMPRESS : Schedule a paint to be executed after a delay, and
    3066             :    * put FrameLayerBuilder in 'compressed' mode that avoids short cut optimizations.
    3067             :    */
    3068             :   enum PaintType {
    3069             :     PAINT_DEFAULT = 0,
    3070             :     PAINT_COMPOSITE_ONLY,
    3071             :     PAINT_DELAYED_COMPRESS
    3072             :   };
    3073             :   void SchedulePaint(PaintType aType = PAINT_DEFAULT, bool aFrameChanged = true);
    3074             : 
    3075             :   // Similar to SchedulePaint() but without calling
    3076             :   // InvalidateRenderingObservers() for SVG.
    3077             :   void SchedulePaintWithoutInvalidatingObservers(
    3078             :     PaintType aType = PAINT_DEFAULT);
    3079             : 
    3080             :   /**
    3081             :    * Checks if the layer tree includes a dedicated layer for this
    3082             :    * frame/display item key pair, and invalidates at least aDamageRect
    3083             :    * area within that layer.
    3084             :    *
    3085             :    * If no layer is found, calls InvalidateFrame() instead.
    3086             :    *
    3087             :    * @param aDamageRect Area of the layer to invalidate.
    3088             :    * @param aFrameDamageRect If no layer is found, the area of the frame to
    3089             :    *                         invalidate. If null, the entire frame will be
    3090             :    *                         invalidated.
    3091             :    * @param aDisplayItemKey Display item type.
    3092             :    * @param aFlags UPDATE_IS_ASYNC : Will skip the invalidation
    3093             :    * if the found layer is being composited by a remote
    3094             :    * compositor.
    3095             :    * @return Layer, if found, nullptr otherwise.
    3096             :    */
    3097             :   enum {
    3098             :     UPDATE_IS_ASYNC = 1 << 0
    3099             :   };
    3100             :   Layer* InvalidateLayer(DisplayItemType aDisplayItemKey,
    3101             :                          const nsIntRect* aDamageRect = nullptr,
    3102             :                          const nsRect* aFrameDamageRect = nullptr,
    3103             :                          uint32_t aFlags = 0);
    3104             : 
    3105             :   void MarkNeedsDisplayItemRebuild();
    3106             : 
    3107             :   /**
    3108             :    * Returns a rect that encompasses everything that might be painted by
    3109             :    * this frame.  This includes this frame, all its descendant frames, this
    3110             :    * frame's outline, and descendant frames' outline, but does not include
    3111             :    * areas clipped out by the CSS "overflow" and "clip" properties.
    3112             :    *
    3113             :    * HasOverflowRects() (below) will return true when this overflow
    3114             :    * rect has been explicitly set, even if it matches mRect.
    3115             :    * XXX Note: because of a space optimization using the formula above,
    3116             :    * during reflow this function does not give accurate data if
    3117             :    * FinishAndStoreOverflow has been called but mRect hasn't yet been
    3118             :    * updated yet.  FIXME: This actually isn't true, but it should be.
    3119             :    *
    3120             :    * The visual overflow rect should NEVER be used for things that
    3121             :    * affect layout.  The scrollable overflow rect is permitted to affect
    3122             :    * layout.
    3123             :    *
    3124             :    * @return the rect relative to this frame's origin, but after
    3125             :    * CSS transforms have been applied (i.e. not really this frame's coordinate
    3126             :    * system, and may not contain the frame's border-box, e.g. if there
    3127             :    * is a CSS transform scaling it down)
    3128             :    */
    3129             :   nsRect GetVisualOverflowRect() const {
    3130             :     return GetOverflowRect(eVisualOverflow);
    3131             :   }
    3132             : 
    3133             :   /**
    3134             :    * Returns a rect that encompasses the area of this frame that the
    3135             :    * user should be able to scroll to reach.  This is similar to
    3136             :    * GetVisualOverflowRect, but does not include outline or shadows, and
    3137             :    * may in the future include more margins than visual overflow does.
    3138             :    * It does not include areas clipped out by the CSS "overflow" and
    3139             :    * "clip" properties.
    3140             :    *
    3141             :    * HasOverflowRects() (below) will return true when this overflow
    3142             :    * rect has been explicitly set, even if it matches mRect.
    3143             :    * XXX Note: because of a space optimization using the formula above,
    3144             :    * during reflow this function does not give accurate data if
    3145             :    * FinishAndStoreOverflow has been called but mRect hasn't yet been
    3146             :    * updated yet.
    3147             :    *
    3148             :    * @return the rect relative to this frame's origin, but after
    3149             :    * CSS transforms have been applied (i.e. not really this frame's coordinate
    3150             :    * system, and may not contain the frame's border-box, e.g. if there
    3151             :    * is a CSS transform scaling it down)
    3152             :    */
    3153             :   nsRect GetScrollableOverflowRect() const {
    3154             :     return GetOverflowRect(eScrollableOverflow);
    3155             :   }
    3156             : 
    3157             :   nsRect GetOverflowRect(nsOverflowType aType) const;
    3158             : 
    3159             :   nsOverflowAreas GetOverflowAreas() const;
    3160             : 
    3161             :   /**
    3162             :    * Same as GetOverflowAreas, except in this frame's coordinate
    3163             :    * system (before transforms are applied).
    3164             :    *
    3165             :    * @return the overflow areas relative to this frame, before any CSS transforms have
    3166             :    * been applied, i.e. in this frame's coordinate system
    3167             :    */
    3168             :   nsOverflowAreas GetOverflowAreasRelativeToSelf() const;
    3169             : 
    3170             :   /**
    3171             :    * Same as GetScrollableOverflowRect, except relative to the parent
    3172             :    * frame.
    3173             :    *
    3174             :    * @return the rect relative to the parent frame, in the parent frame's
    3175             :    * coordinate system
    3176             :    */
    3177             :   nsRect GetScrollableOverflowRectRelativeToParent() const;
    3178             : 
    3179             :   /**
    3180             :    * Same as GetScrollableOverflowRect, except in this frame's coordinate
    3181             :    * system (before transforms are applied).
    3182             :    *
    3183             :    * @return the rect relative to this frame, before any CSS transforms have
    3184             :    * been applied, i.e. in this frame's coordinate system
    3185             :    */
    3186             :   nsRect GetScrollableOverflowRectRelativeToSelf() const;
    3187             : 
    3188             :   /**
    3189             :    * Like GetVisualOverflowRect, except in this frame's
    3190             :    * coordinate system (before transforms are applied).
    3191             :    *
    3192             :    * @return the rect relative to this frame, before any CSS transforms have
    3193             :    * been applied, i.e. in this frame's coordinate system
    3194             :    */
    3195             :   nsRect GetVisualOverflowRectRelativeToSelf() const;
    3196             : 
    3197             :   /**
    3198             :    * Same as GetVisualOverflowRect, except relative to the parent
    3199             :    * frame.
    3200             :    *
    3201             :    * @return the rect relative to the parent frame, in the parent frame's
    3202             :    * coordinate system
    3203             :    */
    3204             :   nsRect GetVisualOverflowRectRelativeToParent() const;
    3205             : 
    3206             :   /**
    3207             :    * Returns this frame's visual overflow rect as it would be before taking
    3208             :    * account of SVG effects or transforms. The rect returned is relative to
    3209             :    * this frame.
    3210             :    */
    3211             :   nsRect GetPreEffectsVisualOverflowRect() const;
    3212             : 
    3213             :   /**
    3214             :    * Store the overflow area in the frame's mOverflow.mVisualDeltas
    3215             :    * fields or as a frame property in the frame manager so that it can
    3216             :    * be retrieved later without reflowing the frame. Returns true if either of
    3217             :    * the overflow areas changed.
    3218             :    */
    3219             :   bool FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
    3220             :                               nsSize aNewSize, nsSize* aOldSize = nullptr,
    3221             :                               const nsStyleDisplay* aStyleDisplay = nullptr);
    3222             : 
    3223             :   bool FinishAndStoreOverflow(ReflowOutput* aMetrics,
    3224             :                               const nsStyleDisplay* aStyleDisplay = nullptr) {
    3225             :     return FinishAndStoreOverflow(aMetrics->mOverflowAreas,
    3226             :                                   nsSize(aMetrics->Width(), aMetrics->Height()),
    3227             :                                   nullptr, aStyleDisplay);
    3228             :   }
    3229             : 
    3230             :   /**
    3231             :    * Returns whether the frame has an overflow rect that is different from
    3232             :    * its border-box.
    3233             :    */
    3234             :   bool HasOverflowAreas() const {
    3235             :     return mOverflow.mType != NS_FRAME_OVERFLOW_NONE;
    3236             :   }
    3237             : 
    3238             :   /**
    3239             :    * Removes any stored overflow rects (visual and scrollable) from the frame.
    3240             :    * Returns true if the overflow changed.
    3241             :    */
    3242             :   bool ClearOverflowRects();
    3243             : 
    3244             :   /**
    3245             :    * Determine whether borders, padding, margins etc should NOT be applied
    3246             :    * on certain sides of the frame.
    3247             :    * @see mozilla::Sides in gfx/2d/BaseMargin.h
    3248             :    * @see mozilla::LogicalSides in layout/generic/WritingModes.h
    3249             :    *
    3250             :    * @note (See also bug 743402, comment 11) GetSkipSides() checks to see
    3251             :    *       if this frame has a previous or next continuation to determine
    3252             :    *       if a side should be skipped.
    3253             :    *       Unfortunately, this only works after reflow has been completed. In
    3254             :    *       lieu of this, during reflow, an ReflowInput parameter can be
    3255             :    *       passed in, indicating that it should be used to determine if sides
    3256             :    *       should be skipped during reflow.
    3257             :    */
    3258             :   Sides GetSkipSides(const ReflowInput* aReflowInput = nullptr) const;
    3259             :   virtual LogicalSides
    3260             :   GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const {
    3261             :     return LogicalSides();
    3262             :   }
    3263             : 
    3264             :   /**
    3265             :    * @returns true if this frame is selected.
    3266             :    */
    3267             :   bool IsSelected() const;
    3268             : 
    3269             :   /**
    3270             :    *  called to discover where this frame, or a parent frame has user-select style
    3271             :    *  applied, which affects that way that it is selected.
    3272             :    *
    3273             :    *  @param aSelectStyle  out param. Returns the type of selection style found
    3274             :    *                        (using values defined in nsStyleConsts.h).
    3275             :    *
    3276             :    *  @return Whether the frame can be selected (i.e. is not affected by
    3277             :    *          user-select: none)
    3278             :    */
    3279             :   bool IsSelectable(mozilla::StyleUserSelect* aSelectStyle) const;
    3280             : 
    3281             :   /**
    3282             :    *  Called to retrieve the SelectionController associated with the frame.
    3283             :    *  @param aSelCon will contain the selection controller associated with
    3284             :    *  the frame.
    3285             :    */
    3286             :   virtual nsresult  GetSelectionController(nsPresContext *aPresContext, nsISelectionController **aSelCon) = 0;
    3287             : 
    3288             :   /**
    3289             :    *  Call to get nsFrameSelection for this frame.
    3290             :    */
    3291             :   already_AddRefed<nsFrameSelection> GetFrameSelection();
    3292             : 
    3293             :   /**
    3294             :    * GetConstFrameSelection returns an object which methods are safe to use for
    3295             :    * example in nsIFrame code.
    3296             :    */
    3297             :   const nsFrameSelection* GetConstFrameSelection() const;
    3298             : 
    3299             :   /**
    3300             :    *  called to find the previous/next character, word, or line  returns the actual
    3301             :    *  nsIFrame and the frame offset.  THIS DOES NOT CHANGE SELECTION STATE
    3302             :    *  uses frame's begin selection state to start. if no selection on this frame will
    3303             :    *  return NS_ERROR_FAILURE
    3304             :    *  @param aPOS is defined in nsFrameSelection
    3305             :    */
    3306             :   virtual nsresult PeekOffset(nsPeekOffsetStruct *aPos);
    3307             : 
    3308             :   /**
    3309             :    *  called to find the previous/next non-anonymous selectable leaf frame.
    3310             :    *  @param aDirection [in] the direction to move in (eDirPrevious or eDirNext)
    3311             :    *  @param aVisual [in] whether bidi caret behavior is visual (true) or logical (false)
    3312             :    *  @param aJumpLines [in] whether to allow jumping across line boundaries
    3313             :    *  @param aScrollViewStop [in] whether to stop when reaching a scroll frame boundary
    3314             :    *  @param aOutFrame [out] the previous/next selectable leaf frame
    3315             :    *  @param aOutOffset [out] 0 indicates that we arrived at the beginning of the output frame;
    3316             :    *                          -1 indicates that we arrived at its end.
    3317             :    *  @param aOutJumpedLine [out] whether this frame and the returned frame are on different lines
    3318             :    *  @param aOutMovedOverNonSelectableText [out] whether we jumped over a non-selectable
    3319             :    *                                              frame during the search
    3320             :    */
    3321             :   nsresult GetFrameFromDirection(nsDirection aDirection, bool aVisual,
    3322             :                                  bool aJumpLines, bool aScrollViewStop,
    3323             :                                  nsIFrame** aOutFrame, int32_t* aOutOffset,
    3324             :                                  bool* aOutJumpedLine, bool* aOutMovedOverNonSelectableText);
    3325             : 
    3326             :   /**
    3327             :    *  called to see if the children of the frame are visible from indexstart to index end.
    3328             :    *  this does not change any state. returns true only if the indexes are valid and any of
    3329             :    *  the children are visible.  for textframes this index is the character index.
    3330             :    *  if aStart = aEnd result will be false
    3331             :    *  @param aStart start index of first child from 0-N (number of children)
    3332             :    *  @param aEnd   end index of last child from 0-N
    3333             :    *  @param aRecurse should this frame talk to siblings to get to the contents other children?
    3334             :    *  @param aFinished did this frame have the aEndIndex? or is there more work to do
    3335             :    *  @param _retval  return value true or false. false = range is not rendered.
    3336             :    */
    3337             :   virtual nsresult CheckVisibility(nsPresContext* aContext, int32_t aStartIndex, int32_t aEndIndex, bool aRecurse, bool *aFinished, bool *_retval)=0;
    3338             : 
    3339             :   /**
    3340             :    * Called to tell a frame that one of its child frames is dirty (i.e.,
    3341             :    * has the NS_FRAME_IS_DIRTY *or* NS_FRAME_HAS_DIRTY_CHILDREN bit
    3342             :    * set).  This should always set the NS_FRAME_HAS_DIRTY_CHILDREN on
    3343             :    * the frame, and may do other work.
    3344             :    */
    3345             :   virtual void ChildIsDirty(nsIFrame* aChild) = 0;
    3346             : 
    3347             :   /**
    3348             :    * Called to retrieve this frame's accessible.
    3349             :    * If this frame implements Accessibility return a valid accessible
    3350             :    * If not return NS_ERROR_NOT_IMPLEMENTED.
    3351             :    * Note: Accessible must be refcountable. Do not implement directly on your frame
    3352             :    * Use a mediatior of some kind.
    3353             :    */
    3354             : #ifdef ACCESSIBILITY
    3355             :   virtual mozilla::a11y::AccType AccessibleType() = 0;
    3356             : #endif
    3357             : 
    3358             :   /**
    3359             :    * Get the frame whose style should be the parent of this frame's style (i.e.,
    3360             :    * provide the parent style).
    3361             :    *
    3362             :    * This frame must either be an ancestor of this frame or a child.  If
    3363             :    * this returns a child frame, then the child frame must be sure to
    3364             :    * return a grandparent or higher!  Furthermore, if a child frame is
    3365             :    * returned it must have the same GetContent() as this frame.
    3366             :    *
    3367             :    * @param aProviderFrame (out) the frame associated with the returned value
    3368             :    *     or nullptr if the style is for display:contents content.
    3369             :    * @return The style that should be the parent of this frame's style. Null is
    3370             :    *         permitted, and means that this frame's style should be the root of
    3371             :    *         the style tree.
    3372             :    */
    3373             :   virtual ComputedStyle* GetParentComputedStyle(nsIFrame** aProviderFrame) const = 0;
    3374             : 
    3375             :   /**
    3376             :    * Called by RestyleManager to update the style of anonymous boxes
    3377             :    * directly associated with this frame.
    3378             :    *
    3379             :    * The passed-in ServoRestyleState can be used to create new ComputedStyles as
    3380             :    * needed, as well as posting changes to the change list.
    3381             :    *
    3382             :    * It's guaranteed to already have a change in it for this frame and this
    3383             :    * frame's content.
    3384             :    *
    3385             :    * This function will be called after this frame's style has already been
    3386             :    * updated.  This function will only be called on frames which have the
    3387             :    * NS_FRAME_OWNS_ANON_BOXES bit set.
    3388             :    */
    3389             :   void UpdateStyleOfOwnedAnonBoxes(mozilla::ServoRestyleState& aRestyleState)
    3390             :   {
    3391             :     if (GetStateBits() & NS_FRAME_OWNS_ANON_BOXES) {
    3392             :       DoUpdateStyleOfOwnedAnonBoxes(aRestyleState);
    3393             :     }
    3394             :   }
    3395             : 
    3396             : protected:
    3397             :   // This does the actual work of UpdateStyleOfOwnedAnonBoxes.  It calls
    3398             :   // AppendDirectlyOwnedAnonBoxes to find all of the anonymous boxes
    3399             :   // owned by this frame, and then updates styles on each of them.
    3400             :   void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoRestyleState& aRestyleState);
    3401             : 
    3402             :   // A helper for DoUpdateStyleOfOwnedAnonBoxes for the specific case
    3403             :   // of the owned anon box being a child of this frame.
    3404             :   void UpdateStyleOfChildAnonBox(nsIFrame* aChildFrame,
    3405             :                                  mozilla::ServoRestyleState& aRestyleState);
    3406             : 
    3407             :   // Allow ServoRestyleState to call UpdateStyleOfChildAnonBox.
    3408             :   friend class mozilla::ServoRestyleState;
    3409             : 
    3410             : public:
    3411             :   // A helper both for UpdateStyleOfChildAnonBox, and to update frame-backed
    3412             :   // pseudo-elements in RestyleManager.
    3413             :   //
    3414             :   // This gets a ComputedStyle that will be the new style for `aChildFrame`, and
    3415             :   // takes care of updating it, calling CalcStyleDifference, and adding to the
    3416             :   // change list as appropriate.
    3417             :   //
    3418             :   // If aContinuationComputedStyle is not Nothing, it should be used for
    3419             :   // continuations instead of aNewComputedStyle.  In either case, changehints
    3420             :   // are only computed based on aNewComputedStyle.
    3421             :   //
    3422             :   // Returns the generated change hint for the frame.
    3423             :   static nsChangeHint UpdateStyleOfOwnedChildFrame(
    3424             :     nsIFrame* aChildFrame,
    3425             :     ComputedStyle* aNewComputedStyle,
    3426             :     mozilla::ServoRestyleState& aRestyleState,
    3427             :     const Maybe<ComputedStyle*>& aContinuationComputedStyle = Nothing());
    3428             : 
    3429             :   struct OwnedAnonBox
    3430             :   {
    3431             :     typedef void (*UpdateStyleFn)(nsIFrame* aOwningFrame,
    3432             :                                   nsIFrame* aAnonBox,
    3433             :                                   mozilla::ServoRestyleState& aRestyleState);
    3434             : 
    3435             :     explicit OwnedAnonBox(nsIFrame* aAnonBoxFrame,
    3436             :                           UpdateStyleFn aUpdateStyleFn = nullptr)
    3437             :       : mAnonBoxFrame(aAnonBoxFrame)
    3438             :       , mUpdateStyleFn(aUpdateStyleFn)
    3439             :     {}
    3440             : 
    3441             :     nsIFrame* mAnonBoxFrame;
    3442             :     UpdateStyleFn mUpdateStyleFn;
    3443             :   };
    3444             : 
    3445             :   /**
    3446             :    * Appends information about all of the anonymous boxes owned by this frame,
    3447             :    * including other anonymous boxes owned by those which this frame owns
    3448             :    * directly.
    3449             :    */
    3450             :   void AppendOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) {
    3451             :     if (GetStateBits() & NS_FRAME_OWNS_ANON_BOXES) {
    3452             :       if (IsInlineFrame()) {
    3453             :         // See comment in nsIFrame::DoUpdateStyleOfOwnedAnonBoxes for why
    3454             :         // we skip nsInlineFrames.
    3455             :         return;
    3456             :       }
    3457             :       DoAppendOwnedAnonBoxes(aResult);
    3458             :     }
    3459             :   }
    3460             : 
    3461             : protected:
    3462             :   // This does the actual work of AppendOwnedAnonBoxes.
    3463             :   void DoAppendOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult);
    3464             : 
    3465             : public:
    3466             :   /**
    3467             :    * Hook subclasses can override to return their owned anonymous boxes.
    3468             :    *
    3469             :    * This function only appends anonymous boxes that are directly owned by
    3470             :    * this frame, i.e. direct children or (for certain frames) a wrapper
    3471             :    * parent, unlike AppendOwnedAnonBoxes, which will append all anonymous
    3472             :    * boxes transitively owned by this frame.
    3473             :    */
    3474             :   virtual void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult);
    3475             : 
    3476             :   /**
    3477             :    * Determines whether a frame is visible for painting;
    3478             :    * taking into account whether it is painting a selection or printing.
    3479             :    */
    3480             :   bool IsVisibleForPainting(nsDisplayListBuilder* aBuilder);
    3481             :   /**
    3482             :    * Determines whether a frame is visible for painting or collapsed;
    3483             :    * taking into account whether it is painting a selection or printing,
    3484             :    */
    3485             :   bool IsVisibleOrCollapsedForPainting(nsDisplayListBuilder* aBuilder);
    3486             :   /**
    3487             :    * As above, but slower because we have to recompute some stuff that
    3488             :    * aBuilder already has.
    3489             :    */
    3490             :   bool IsVisibleForPainting();
    3491             :   /**
    3492             :    * Check whether this frame is visible in the current selection. Returns
    3493             :    * true if there is no current selection.
    3494             :    */
    3495             :   bool IsVisibleInSelection(nsDisplayListBuilder* aBuilder);
    3496             : 
    3497             :   /**
    3498             :    * Overridable function to determine whether this frame should be considered
    3499             :    * "in" the given non-null aSelection for visibility purposes.
    3500             :    */
    3501             :   virtual bool IsVisibleInSelection(mozilla::dom::Selection* aSelection);
    3502             : 
    3503             :   /**
    3504             :    * Determines if this frame has a container effect that requires
    3505             :    * it to paint as a visually atomic unit.
    3506             :    */
    3507             :   bool IsVisuallyAtomic(mozilla::EffectSet* aEffectSet,
    3508             :                         const nsStyleDisplay* aStyleDisplay,
    3509             :                         const nsStyleEffects* aStyleEffects);
    3510             : 
    3511             :   /**
    3512             :    * Determines if this frame is a stacking context.
    3513             :    *
    3514             :    * @param aIsPositioned The precomputed result of IsAbsPosContainingBlock
    3515             :    * on the StyleDisplay().
    3516             :    * @param aIsVisuallyAtomic The precomputed result of IsVisuallyAtomic.
    3517             :    */
    3518             :   bool IsStackingContext(const nsStyleDisplay* aStyleDisplay,
    3519             :                          const nsStylePosition* aStylePosition,
    3520             :                          bool aIsPositioned,
    3521             :                          bool aIsVisuallyAtomic);
    3522             :   bool IsStackingContext();
    3523             : 
    3524             :   virtual bool HonorPrintBackgroundSettings() { return true; }
    3525             : 
    3526             :   /**
    3527             :    * Determine whether the frame is logically empty, which is roughly
    3528             :    * whether the layout would be the same whether or not the frame is
    3529             :    * present.  Placeholder frames should return true.  Block frames
    3530             :    * should be considered empty whenever margins collapse through them,
    3531             :    * even though those margins are relevant.  Text frames containing
    3532             :    * only whitespace that does not contribute to the height of the line
    3533             :    * should return true.
    3534             :    */
    3535             :   virtual bool IsEmpty() = 0;
    3536             :   /**
    3537             :    * Return the same as IsEmpty(). This may only be called after the frame
    3538             :    * has been reflowed and before any further style or content changes.
    3539             :    */
    3540             :   virtual bool CachedIsEmpty();
    3541             :   /**
    3542             :    * Determine whether the frame is logically empty, assuming that all
    3543             :    * its children are empty.
    3544             :    */
    3545             :   virtual bool IsSelfEmpty() = 0;
    3546             : 
    3547             :   /**
    3548             :    * IsGeneratedContentFrame returns whether a frame corresponds to
    3549             :    * generated content
    3550             :    *
    3551             :    * @return whether the frame correspods to generated content
    3552             :    */
    3553             :   bool IsGeneratedContentFrame() const {
    3554             :     return (mState & NS_FRAME_GENERATED_CONTENT) != 0;
    3555             :   }
    3556             : 
    3557             :   /**
    3558             :    * IsPseudoFrame returns whether a frame is a pseudo frame (eg an
    3559             :    * anonymous table-row frame created for a CSS table-cell without an
    3560             :    * enclosing table-row.
    3561             :    *
    3562             :    * @param aParentContent the content node corresponding to the parent frame
    3563             :    * @return whether the frame is a pseudo frame
    3564             :    */
    3565             :   bool IsPseudoFrame(const nsIContent* aParentContent) {
    3566             :     return mContent == aParentContent;
    3567             :   }
    3568             : 
    3569             :   /**
    3570             :    * Support for reading and writing properties on the frame.
    3571             :    * These call through to the frame's FrameProperties object, if it
    3572             :    * exists, but avoid creating it if no property is ever set.
    3573             :    */
    3574             :   template<typename T>
    3575             :   FrameProperties::PropertyType<T>
    3576             :   GetProperty(FrameProperties::Descriptor<T> aProperty,
    3577             :               bool* aFoundResult = nullptr) const
    3578             :   {
    3579           0 :     return mProperties.Get(aProperty, aFoundResult);
    3580             :   }
    3581             : 
    3582             :   template<typename T>
    3583             :   bool HasProperty(FrameProperties::Descriptor<T> aProperty) const
    3584             :   {
    3585             :     return mProperties.Has(aProperty);
    3586             :   }
    3587             : 
    3588             :   // Add a property, or update an existing property for the given descriptor.
    3589             :   template<typename T>
    3590             :   void SetProperty(FrameProperties::Descriptor<T> aProperty,
    3591             :                    FrameProperties::PropertyType<T> aValue)
    3592             :   {
    3593             :     mProperties.Set(aProperty, aValue, this);
    3594             :   }
    3595             : 
    3596             :   // Unconditionally add a property; use ONLY if the descriptor is known
    3597             :   // to NOT already be present.
    3598             :   template<typename T>
    3599             :   void AddProperty(FrameProperties::Descriptor<T> aProperty,
    3600             :                    FrameProperties::PropertyType<T> aValue)
    3601             :   {
    3602             :     mProperties.Add(aProperty, aValue);
    3603             :   }
    3604             : 
    3605             :   template<typename T>
    3606             :   FrameProperties::PropertyType<T>
    3607             :   RemoveProperty(FrameProperties::Descriptor<T> aProperty,
    3608             :                  bool* aFoundResult = nullptr)
    3609             :   {
    3610             :     return mProperties.Remove(aProperty, aFoundResult);
    3611             :   }
    3612             : 
    3613             :   template<typename T>
    3614             :   void DeleteProperty(FrameProperties::Descriptor<T> aProperty)
    3615             :   {
    3616             :     mProperties.Delete(aProperty, this);
    3617             :   }
    3618             : 
    3619             :   void DeleteAllProperties()
    3620             :   {
    3621             :     mProperties.DeleteAll(this);
    3622             :   }
    3623             : 
    3624             :   // nsIFrames themselves are in the nsPresArena, and so are not measured here.
    3625             :   // Instead, this measures heap-allocated things hanging off the nsIFrame, and
    3626             :   // likewise for its descendants.
    3627             :   void AddSizeOfExcludingThisForTree(nsWindowSizes& aWindowSizes) const;
    3628             : 
    3629             :   /**
    3630             :    * Return true if and only if this frame obeys visibility:hidden.
    3631             :    * if it does not, then nsContainerFrame will hide its view even though
    3632             :    * this means children can't be made visible again.
    3633             :    */
    3634             :   virtual bool SupportsVisibilityHidden() { return true; }
    3635             : 
    3636             :   /**
    3637             :    * Returns the clip rect set via the 'clip' property, if the 'clip' property
    3638             :    * applies to this frame; otherwise returns Nothing(). The 'clip' property
    3639             :    * applies to HTML frames if they are absolutely positioned. The 'clip'
    3640             :    * property applies to SVG frames regardless of the value of the 'position'
    3641             :    * property.
    3642             :    *
    3643             :    * The coordinates of the returned rectangle are relative to this frame's
    3644             :    * origin.
    3645             :    */
    3646             :   Maybe<nsRect> GetClipPropClipRect(const nsStyleDisplay* aDisp,
    3647             :                                     const nsStyleEffects* aEffects,
    3648             :                                     const nsSize& aSize) const;
    3649             : 
    3650             :   /**
    3651             :    * Check if this frame is focusable and in the current tab order.
    3652             :    * Tabbable is indicated by a nonnegative tabindex & is a subset of focusable.
    3653             :    * For example, only the selected radio button in a group is in the
    3654             :    * tab order, unless the radio group has no selection in which case
    3655             :    * all of the visible, non-disabled radio buttons in the group are
    3656             :    * in the tab order. On the other hand, all of the visible, non-disabled
    3657             :    * radio buttons are always focusable via clicking or script.
    3658             :    * Also, depending on the pref accessibility.tabfocus some widgets may be
    3659             :    * focusable but removed from the tab order. This is the default on
    3660             :    * Mac OS X, where fewer items are focusable.
    3661             :    * @param  [in, optional] aTabIndex the computed tab index
    3662             :    *         < 0 if not tabbable
    3663             :    *         == 0 if in normal tab order
    3664             :    *         > 0 can be tabbed to in the order specified by this value
    3665             :    * @param  [in, optional] aWithMouse, is this focus query for mouse clicking
    3666             :    * @return whether the frame is focusable via mouse, kbd or script.
    3667             :    */
    3668             :   virtual bool IsFocusable(int32_t *aTabIndex = nullptr, bool aWithMouse = false);
    3669             : 
    3670             :   // BOX LAYOUT METHODS
    3671             :   // These methods have been migrated from nsIBox and are in the process of
    3672             :   // being refactored. DO NOT USE OUTSIDE OF XUL.
    3673             :   bool IsXULBoxFrame() const
    3674             :   {
    3675             :     return IsFrameOfType(nsIFrame::eXULBox);
    3676             :   }
    3677             : 
    3678             :   enum Halignment {
    3679             :     hAlign_Left,
    3680             :     hAlign_Right,
    3681             :     hAlign_Center
    3682             :   };
    3683             : 
    3684             :   enum Valignment {
    3685             :     vAlign_Top,
    3686             :     vAlign_Middle,
    3687             :     vAlign_BaseLine,
    3688             :     vAlign_Bottom
    3689             :   };
    3690             : 
    3691             :   /**
    3692             :    * This calculates the minimum size required for a box based on its state
    3693             :    * @param[in] aBoxLayoutState The desired state to calculate for
    3694             :    * @return The minimum size
    3695             :    */
    3696             :   virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) = 0;
    3697             : 
    3698             :   /**
    3699             :    * This calculates the preferred size of a box based on its state
    3700             :    * @param[in] aBoxLayoutState The desired state to calculate for
    3701             :    * @return The preferred size
    3702             :    */
    3703             :   virtual nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) = 0;
    3704             : 
    3705             :   /**
    3706             :    * This calculates the maximum size for a box based on its state
    3707             :    * @param[in] aBoxLayoutState The desired state to calculate for
    3708             :    * @return The maximum size
    3709             :    */
    3710             :   virtual nsSize GetXULMaxSize(nsBoxLayoutState& aBoxLayoutState) = 0;
    3711             : 
    3712             :   /**
    3713             :    * This returns the minimum size for the scroll area if this frame is
    3714             :    * being scrolled. Usually it's (0,0).
    3715             :    */
    3716             :   virtual nsSize GetXULMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState) = 0;
    3717             : 
    3718             :   // Implemented in nsBox, used in nsBoxFrame
    3719             :   uint32_t GetXULOrdinal();
    3720             : 
    3721             :   virtual nscoord GetXULFlex() = 0;
    3722             :   virtual nscoord GetXULBoxAscent(nsBoxLayoutState& aBoxLayoutState) = 0;
    3723             :   virtual bool IsXULCollapsed() = 0;
    3724             :   // This does not alter the overflow area. If the caller is changing
    3725             :   // the box size, the caller is responsible for updating the overflow
    3726             :   // area. It's enough to just call XULLayout or SyncLayout on the
    3727             :   // box. You can pass true to aRemoveOverflowArea as a
    3728             :   // convenience.
    3729             :   virtual void SetXULBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect,
    3730             :                             bool aRemoveOverflowAreas = false) = 0;
    3731             :   nsresult XULLayout(nsBoxLayoutState& aBoxLayoutState);
    3732             :   // Box methods.  Note that these do NOT just get the CSS border, padding,
    3733             :   // etc.  They also talk to nsITheme.
    3734             :   virtual nsresult GetXULBorderAndPadding(nsMargin& aBorderAndPadding);
    3735             :   virtual nsresult GetXULBorder(nsMargin& aBorder)=0;
    3736             :   virtual nsresult GetXULPadding(nsMargin& aBorderAndPadding)=0;
    3737             :   virtual nsresult GetXULMargin(nsMargin& aMargin)=0;
    3738             :   virtual void SetXULLayoutManager(nsBoxLayout* aLayout) { }
    3739             :   virtual nsBoxLayout* GetXULLayoutManager() { return nullptr; }
    3740             :   nsresult GetXULClientRect(nsRect& aContentRect);
    3741             : 
    3742             :   virtual uint32_t GetXULLayoutFlags()
    3743             :   { return 0; }
    3744             : 
    3745             :   // For nsSprocketLayout
    3746             :   virtual Valignment GetXULVAlign() const = 0;
    3747             :   virtual Halignment GetXULHAlign() const = 0;
    3748             : 
    3749             :   bool IsXULHorizontal() const { return (mState & NS_STATE_IS_HORIZONTAL) != 0; }
    3750             :   bool IsXULNormalDirection() const { return (mState & NS_STATE_IS_DIRECTION_NORMAL) != 0; }
    3751             : 
    3752             :   nsresult XULRedraw(nsBoxLayoutState& aState);
    3753             :   virtual nsresult XULRelayoutChildAtOrdinal(nsIFrame* aChild)=0;
    3754             : 
    3755             :   static bool AddXULPrefSize(nsIFrame* aBox, nsSize& aSize, bool& aWidth, bool& aHeightSet);
    3756             :   static bool AddXULMinSize(nsBoxLayoutState& aState, nsIFrame* aBox,
    3757             :                             nsSize& aSize, bool& aWidth, bool& aHeightSet);
    3758             :   static bool AddXULMaxSize(nsIFrame* aBox, nsSize& aSize, bool& aWidth, bool& aHeightSet);
    3759             :   static bool AddXULFlex(nsIFrame* aBox, nscoord& aFlex);
    3760             : 
    3761             :   // END OF BOX LAYOUT METHODS
    3762             :   // The above methods have been migrated from nsIBox and are in the process of
    3763             :   // being refactored. DO NOT USE OUTSIDE OF XUL.
    3764             : 
    3765             :   /**
    3766             :    * @return true if this text frame ends with a newline character.  It
    3767             :    * should return false if this is not a text frame.
    3768             :    */
    3769             :   virtual bool HasSignificantTerminalNewline() const;
    3770             : 
    3771             :   struct CaretPosition {
    3772             :     CaretPosition();
    3773             :     ~CaretPosition();
    3774             : 
    3775             :     nsCOMPtr<nsIContent> mResultContent;
    3776             :     int32_t              mContentOffset;
    3777             :   };
    3778             : 
    3779             :   /**
    3780             :    * gets the first or last possible caret position within the frame
    3781             :    *
    3782             :    * @param  [in] aStart
    3783             :    *         true  for getting the first possible caret position
    3784             :    *         false for getting the last possible caret position
    3785             :    * @return The caret position in a CaretPosition.
    3786             :    *         the returned value is a 'best effort' in case errors
    3787             :    *         are encountered rummaging through the frame.
    3788             :    */
    3789             :   CaretPosition GetExtremeCaretPosition(bool aStart);
    3790             : 
    3791             :   /**
    3792             :    * Get a line iterator for this frame, if supported.
    3793             :    *
    3794             :    * @return nullptr if no line iterator is supported.
    3795             :    * @note dispose the line iterator using nsILineIterator::DisposeLineIterator
    3796             :    */
    3797             :   virtual nsILineIterator* GetLineIterator() = 0;
    3798             : 
    3799             :   /**
    3800             :    * If this frame is a next-in-flow, and its prev-in-flow has something on its
    3801             :    * overflow list, pull those frames into the child list of this one.
    3802             :    */
    3803             :   virtual void PullOverflowsFromPrevInFlow() {}
    3804             : 
    3805             :   /**
    3806             :    * Clear the list of child PresShells generated during the last paint
    3807             :    * so that we can begin generating a new one.
    3808             :    */
    3809             :   void ClearPresShellsFromLastPaint() {
    3810             :     PaintedPresShellList()->Clear();
    3811             :   }
    3812             : 
    3813             :   /**
    3814             :    * Flag a child PresShell as painted so that it will get its paint count
    3815             :    * incremented during empty transactions.
    3816             :    */
    3817             :   void AddPaintedPresShell(nsIPresShell* shell) {
    3818             :     PaintedPresShellList()->AppendElement(do_GetWeakReference(shell));
    3819             :   }
    3820             : 
    3821             :   /**
    3822             :    * Increment the paint count of all child PresShells that were painted during
    3823             :    * the last repaint.
    3824             :    */
    3825             :   void UpdatePaintCountForPaintedPresShells() {
    3826             :     for (nsWeakPtr& item : *PaintedPresShellList()) {
    3827             :       nsCOMPtr<nsIPresShell> shell = do_QueryReferent(item);
    3828             :       if (shell) {
    3829             :         shell->IncrementPaintCount();
    3830             :       }
    3831             :     }
    3832             :   }
    3833             : 
    3834             :   /**
    3835             :    * @return true if we painted @aShell during the last repaint.
    3836             :    */
    3837             :   bool DidPaintPresShell(nsIPresShell* aShell)
    3838             :   {
    3839             :     for (nsWeakPtr& item : *PaintedPresShellList()) {
    3840             :       nsCOMPtr<nsIPresShell> shell = do_QueryReferent(item);
    3841             :       if (shell == aShell) {
    3842             :         return true;
    3843             :       }
    3844             :     }
    3845             :     return false;
    3846             :   }
    3847             : 
    3848             :   /**
    3849             :    * Accessors for the absolute containing block.
    3850             :    */
    3851             :   bool IsAbsoluteContainer() const { return !!(mState & NS_FRAME_HAS_ABSPOS_CHILDREN); }
    3852             :   bool HasAbsolutelyPositionedChildren() const;
    3853             :   nsAbsoluteContainingBlock* GetAbsoluteContainingBlock() const;
    3854             :   void MarkAsAbsoluteContainingBlock();
    3855             :   void MarkAsNotAbsoluteContainingBlock();
    3856             :   // Child frame types override this function to select their own child list name
    3857             :   virtual mozilla::layout::FrameChildListID GetAbsoluteListID() const { return kAbsoluteList; }
    3858             : 
    3859             :   // Checks if we (or any of our descendents) have NS_FRAME_PAINTED_THEBES set, and
    3860             :   // clears this bit if so.
    3861             :   bool CheckAndClearPaintedState();
    3862             : 
    3863             :   // Checks if we (or any of our descendents) have mBuiltDisplayList set, and
    3864             :   // clears this bit if so.
    3865             :   bool CheckAndClearDisplayListState();
    3866             : 
    3867             :   // CSS visibility just doesn't cut it because it doesn't inherit through
    3868             :   // documents. Also if this frame is in a hidden card of a deck then it isn't
    3869             :   // visible either and that isn't expressed using CSS visibility. Also if it
    3870             :   // is in a hidden view (there are a few cases left and they are hopefully
    3871             :   // going away soon).
    3872             :   // If the VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY flag is passed then we
    3873             :   // ignore the chrome/content boundary, otherwise we stop looking when we
    3874             :   // reach it.
    3875             :   enum {
    3876             :     VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY = 0x01
    3877             :   };
    3878             :   bool IsVisibleConsideringAncestors(uint32_t aFlags = 0) const;
    3879             : 
    3880             :   struct FrameWithDistance
    3881             :   {
    3882             :     nsIFrame* mFrame;
    3883             :     nscoord mXDistance;
    3884             :     nscoord mYDistance;
    3885             :   };
    3886             : 
    3887             :   /**
    3888             :    * Finds a frame that is closer to a specified point than a current
    3889             :    * distance.  Distance is measured as for text selection -- a closer x
    3890             :    * distance beats a closer y distance.
    3891             :    *
    3892             :    * Normally, this function will only check the distance between this
    3893             :    * frame's rectangle and the specified point.  SVGTextFrame overrides
    3894             :    * this so that it can manage all of its descendant frames and take
    3895             :    * into account any SVG text layout.
    3896             :    *
    3897             :    * If aPoint is closer to this frame's rectangle than aCurrentBestFrame
    3898             :    * indicates, then aCurrentBestFrame is updated with the distance between
    3899             :    * aPoint and this frame's rectangle, and with a pointer to this frame.
    3900             :    * If aPoint is not closer, then aCurrentBestFrame is left unchanged.
    3901             :    *
    3902             :    * @param aPoint The point to check for its distance to this frame.
    3903             :    * @param aCurrentBestFrame Pointer to a struct that will be updated with
    3904             :    *   a pointer to this frame and its distance to aPoint, if this frame
    3905             :    *   is indeed closer than the current distance in aCurrentBestFrame.
    3906             :    */
    3907             :   virtual void FindCloserFrameForSelection(const nsPoint& aPoint,
    3908             :                                            FrameWithDistance* aCurrentBestFrame);
    3909             : 
    3910             :   /**
    3911             :    * Is this a flex item? (i.e. a non-abs-pos child of a flex container)
    3912             :    */
    3913             :   inline bool IsFlexItem() const;
    3914             :   /**
    3915             :    * Is this a flex or grid item? (i.e. a non-abs-pos child of a flex/grid container)
    3916             :    */
    3917             :   inline bool IsFlexOrGridItem() const;
    3918             :   inline bool IsFlexOrGridContainer() const;
    3919             : 
    3920             :   /**
    3921             :    * @return true if this frame is used as a table caption.
    3922             :    */
    3923             :   inline bool IsTableCaption() const;
    3924             : 
    3925             :   inline bool IsBlockInside() const;
    3926             :   inline bool IsBlockOutside() const;
    3927             :   inline bool IsInlineOutside() const;
    3928             :   inline mozilla::StyleDisplay GetDisplay() const;
    3929             :   inline bool IsFloating() const;
    3930             :   inline bool IsAbsPosContainingBlock() const;
    3931             :   inline bool IsFixedPosContainingBlock() const;
    3932             :   inline bool IsRelativelyPositioned() const;
    3933             :   inline bool IsAbsolutelyPositioned(const nsStyleDisplay* aStyleDisplay = nullptr) const;
    3934             : 
    3935             :   /**
    3936             :    * Returns the vertical-align value to be used for layout, if it is one
    3937             :    * of the enumerated values.  If this is an SVG text frame, it returns a value
    3938             :    * that corresponds to the value of dominant-baseline.  If the
    3939             :    * vertical-align property has length or percentage value, this returns
    3940             :    * eInvalidVerticalAlign.
    3941             :    */
    3942             :   uint8_t VerticalAlignEnum() const;
    3943             :   enum { eInvalidVerticalAlign = 0xFF };
    3944             : 
    3945             :   void CreateOwnLayerIfNeeded(nsDisplayListBuilder* aBuilder, nsDisplayList* aList,
    3946             :                               bool* aCreatedContainerItem = nullptr);
    3947             : 
    3948             :   /**
    3949             :    * Adds the NS_FRAME_IN_POPUP state bit to aFrame, and
    3950             :    * all descendant frames (including cross-doc ones).
    3951             :    */
    3952             :   static void AddInPopupStateBitToDescendants(nsIFrame* aFrame);
    3953             :   /**
    3954             :    * Removes the NS_FRAME_IN_POPUP state bit from aFrame and
    3955             :    * all descendant frames (including cross-doc ones), unless
    3956             :    * the frame is a popup itself.
    3957             :    */
    3958             :   static void RemoveInPopupStateBitFromDescendants(nsIFrame* aFrame);
    3959             : 
    3960             :   /**
    3961             :    * Sorts the given nsFrameList, so that for every two adjacent frames in the
    3962             :    * list, the former is less than or equal to the latter, according to the
    3963             :    * templated IsLessThanOrEqual method.
    3964             :    *
    3965             :    * Note: this method uses a stable merge-sort algorithm.
    3966             :    */
    3967             :   template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
    3968             :   static void SortFrameList(nsFrameList& aFrameList);
    3969             : 
    3970             :   /**
    3971             :    * Returns true if the given frame list is already sorted, according to the
    3972             :    * templated IsLessThanOrEqual function.
    3973             :    */
    3974             :   template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
    3975             :   static bool IsFrameListSorted(nsFrameList& aFrameList);
    3976             : 
    3977             :   /**
    3978             :    * Return true if aFrame is in an {ib} split and is NOT one of the
    3979             :    * continuations of the first inline in it.
    3980             :    */
    3981             :   bool FrameIsNonFirstInIBSplit() const {
    3982             :     return (GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) &&
    3983             :       FirstContinuation()->GetProperty(nsIFrame::IBSplitPrevSibling());
    3984             :   }
    3985             : 
    3986             :   /**
    3987             :    * Return true if aFrame is in an {ib} split and is NOT one of the
    3988             :    * continuations of the last inline in it.
    3989             :    */
    3990             :   bool FrameIsNonLastInIBSplit() const {
    3991             :     return (GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) &&
    3992             :       FirstContinuation()->GetProperty(nsIFrame::IBSplitSibling());
    3993             :   }
    3994             : 
    3995             :   /**
    3996             :    * Return whether this is a frame whose width is used when computing
    3997             :    * the font size inflation of its descendants.
    3998             :    */
    3999             :   bool IsContainerForFontSizeInflation() const {
    4000             :     return GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER;
    4001             :   }
    4002             : 
    4003             :   /**
    4004             :    * Return whether this frame keeps track of overflow areas. (Frames for
    4005             :    * non-display SVG elements -- e.g. <clipPath> -- do not maintain overflow
    4006             :    * areas, because they're never painted.)
    4007             :    */
    4008             :   bool FrameMaintainsOverflow() const {
    4009             :     return !HasAllStateBits(NS_FRAME_SVG_LAYOUT | NS_FRAME_IS_NONDISPLAY);
    4010             :   }
    4011             : 
    4012             :   /*
    4013             :    * @param aStyleDisplay:  If the caller has this->StyleDisplay(), providing
    4014             :    *   it here will improve performance.
    4015             :    */
    4016             :   bool BackfaceIsHidden(const nsStyleDisplay* aStyleDisplay) const {
    4017             :     MOZ_ASSERT(aStyleDisplay == StyleDisplay());
    4018             :     return aStyleDisplay->BackfaceIsHidden();
    4019             :   }
    4020           0 :   bool BackfaceIsHidden() const {
    4021           0 :     return StyleDisplay()->BackfaceIsHidden();
    4022             :   }
    4023             : 
    4024             :   /**
    4025             :    * Returns true if the frame is scrolled out of view.
    4026             :    */
    4027             :   bool IsScrolledOutOfView();
    4028             : 
    4029             :   /**
    4030             :    * Computes a 2D matrix from the -moz-window-transform and
    4031             :    * -moz-window-transform-origin properties on aFrame.
    4032             :    * Values that don't result in a 2D matrix will be ignored and an identity
    4033             :    * matrix will be returned instead.
    4034             :    */
    4035             :   Matrix ComputeWidgetTransform();
    4036             : 
    4037             :   /**
    4038             :    * Applies the values from the -moz-window-* properties to the widget.
    4039             :    */
    4040             :   virtual void UpdateWidgetProperties();
    4041             : 
    4042             :   /**
    4043             :    * @return true iff this frame has one or more associated image requests.
    4044             :    * @see mozilla::css::ImageLoader.
    4045             :    */
    4046             :   bool HasImageRequest() const { return mHasImageRequest; }
    4047             : 
    4048             :   /**
    4049             :    * Update this frame's image request state.
    4050             :    */
    4051             :   void SetHasImageRequest(bool aHasRequest) { mHasImageRequest = aHasRequest; }
    4052             : 
    4053             :   /**
    4054             :    * Whether this frame has a first-letter child.  If it does, the frame is
    4055             :    * actually an nsContainerFrame and the first-letter frame can be gotten by
    4056             :    * walking up to the nearest ancestor blockframe and getting its first
    4057             :    * continuation's nsContainerFrame::FirstLetterProperty() property.  This will
    4058             :    * only return true for the first continuation of the first-letter's parent.
    4059             :    */
    4060             :   bool HasFirstLetterChild() const { return mHasFirstLetterChild; }
    4061             : 
    4062             :   /**
    4063             :    * Whether this frame's parent is a wrapper anonymous box.  See documentation
    4064             :    * for mParentIsWrapperAnonBox.
    4065             :    */
    4066             :   bool ParentIsWrapperAnonBox() const { return mParentIsWrapperAnonBox; }
    4067             :   void SetParentIsWrapperAnonBox() { mParentIsWrapperAnonBox = true; }
    4068             : 
    4069             :   /**
    4070             :    * Whether this is a wrapper anonymous box needing a restyle.
    4071             :    */
    4072             :   bool IsWrapperAnonBoxNeedingRestyle() const {
    4073             :     return mIsWrapperBoxNeedingRestyle;
    4074             :   }
    4075             :   void SetIsWrapperAnonBoxNeedingRestyle(bool aNeedsRestyle) {
    4076             :     mIsWrapperBoxNeedingRestyle = aNeedsRestyle;
    4077             :   }
    4078             : 
    4079             :   bool MayHaveTransformAnimation() const {
    4080             :     return mMayHaveTransformAnimation;
    4081             :   }
    4082             :   void SetMayHaveTransformAnimation() {
    4083           0 :     mMayHaveTransformAnimation = true;
    4084             :   }
    4085             :   bool MayHaveOpacityAnimation() const {
    4086             :     return mMayHaveOpacityAnimation;
    4087             :   }
    4088             :   void SetMayHaveOpacityAnimation() {
    4089           4 :     mMayHaveOpacityAnimation = true;
    4090             :   }
    4091             : 
    4092             :   // Returns true if this frame is visible or may have visible descendants.
    4093           2 :   bool IsVisibleOrMayHaveVisibleDescendants() const {
    4094           0 :     return !mAllDescendantsAreInvisible || StyleVisibility()->IsVisible();
    4095             :   }
    4096             :   // Update mAllDescendantsAreInvisible flag for this frame and ancestors.
    4097             :   void UpdateVisibleDescendantsState();
    4098             : 
    4099             :   /**
    4100             :    * If this returns true, the frame it's called on should get the
    4101             :    * NS_FRAME_HAS_DIRTY_CHILDREN bit set on it by the caller; either directly
    4102             :    * if it's already in reflow, or via calling FrameNeedsReflow() to schedule a
    4103             :    * reflow.
    4104             :    */
    4105             :   virtual bool RenumberFrameAndDescendants(int32_t* aOrdinal,
    4106             :                                            int32_t aDepth,
    4107             :                                            int32_t aIncrement,
    4108             :                                            bool aForCounting) { return false; }
    4109             : 
    4110             :   /**
    4111             :    * Helper function - computes the content-box inline size for aCoord.
    4112             :    */
    4113             :   nscoord ComputeISizeValue(gfxContext*         aRenderingContext,
    4114             :                             nscoord             aContainingBlockISize,
    4115             :                             nscoord             aContentEdgeToBoxSizing,
    4116             :                             nscoord             aBoxSizingToMarginEdge,
    4117             :                             const nsStyleCoord& aCoord,
    4118             :                             ComputeSizeFlags    aFlags = eDefault);
    4119             : 
    4120             :   DisplayItemDataArray& DisplayItemData() { return mDisplayItemData; }
    4121             : 
    4122             :   void AddDisplayItem(nsDisplayItem* aItem);
    4123             :   bool RemoveDisplayItem(nsDisplayItem* aItem);
    4124             :   void RemoveDisplayItemDataForDeletion();
    4125             :   bool HasDisplayItems();
    4126             :   bool HasDisplayItem(nsDisplayItem* aItem);
    4127             : 
    4128             :   bool ForceDescendIntoIfVisible() { return mForceDescendIntoIfVisible; }
    4129             :   void SetForceDescendIntoIfVisible(bool aForce) { mForceDescendIntoIfVisible = aForce; }
    4130             : 
    4131             :   bool BuiltDisplayList() { return mBuiltDisplayList; }
    4132             :   void SetBuiltDisplayList(bool aBuilt) { mBuiltDisplayList = aBuilt; }
    4133             : 
    4134             :   bool IsFrameModified() { return mFrameIsModified; }
    4135             :   void SetFrameIsModified(bool aFrameIsModified) { mFrameIsModified = aFrameIsModified; }
    4136             : 
    4137             :   bool HasOverrideDirtyRegion() { return mHasOverrideDirtyRegion; }
    4138             :   void SetHasOverrideDirtyRegion(bool aHasDirtyRegion) { mHasOverrideDirtyRegion = aHasDirtyRegion; }
    4139             : 
    4140             :   bool MayHaveWillChangeBudget() { return mMayHaveWillChangeBudget; }
    4141             :   void SetMayHaveWillChangeBudget(bool aHasBudget) { mMayHaveWillChangeBudget = aHasBudget; }
    4142             : 
    4143             :   /**
    4144             :    * Returns the set of flags indicating the properties of the frame that the
    4145             :    * compositor might care about for hit-testing purposes. Note that this function
    4146             :    * must be called during Gecko display list construction time (i.e while the
    4147             :    * frame tree is being traversed) because that is when the display list builder
    4148             :    * has the necessary state set up correctly.
    4149             :    */
    4150             :   mozilla::gfx::CompositorHitTestInfo GetCompositorHitTestInfo(nsDisplayListBuilder* aBuilder);
    4151             : 
    4152             : protected:
    4153             :   static void DestroyAnonymousContent(nsPresContext* aPresContext,
    4154             :                                       already_AddRefed<nsIContent>&& aContent);
    4155             : 
    4156             :   /**
    4157             :    * Reparent this frame's view if it has one.
    4158             :    */
    4159             :   void ReparentFrameViewTo(nsViewManager* aViewManager,
    4160             :                            nsView*        aNewParentView,
    4161             :                            nsView*        aOldParentView);
    4162             : 
    4163             :   /**
    4164             :    * To be overridden by frame classes that have a varying IsLeaf() state and
    4165             :    * is indicating that with DynamicLeaf in nsFrameIdList.h.
    4166             :    * @see IsLeaf()
    4167             :    */
    4168             :   virtual bool IsLeafDynamic() const { return false; }
    4169             : 
    4170             :   // Members
    4171             :   nsRect                 mRect;
    4172             :   nsCOMPtr<nsIContent>   mContent;
    4173             :   RefPtr<ComputedStyle> mComputedStyle;
    4174             : private:
    4175             :   nsContainerFrame* mParent;
    4176             :   nsIFrame*        mNextSibling;  // doubly-linked list of frames
    4177             :   nsIFrame*        mPrevSibling;  // Do not touch outside SetNextSibling!
    4178             : 
    4179             :   DisplayItemDataArray mDisplayItemData;
    4180             : 
    4181             :   void MarkAbsoluteFramesForDisplayList(nsDisplayListBuilder* aBuilder);
    4182             : 
    4183             :   static void DestroyPaintedPresShellList(nsTArray<nsWeakPtr>* list) {
    4184             :     list->Clear();
    4185             :     delete list;
    4186             :   }
    4187             : 
    4188             :   // Stores weak references to all the PresShells that were painted during
    4189             :   // the last paint event so that we can increment their paint count during
    4190             :   // empty transactions
    4191             :   NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(PaintedPresShellsProperty,
    4192             :                                       nsTArray<nsWeakPtr>,
    4193             :                                       DestroyPaintedPresShellList)
    4194             : 
    4195             :   nsTArray<nsWeakPtr>* PaintedPresShellList() {
    4196             :     nsTArray<nsWeakPtr>* list = GetProperty(PaintedPresShellsProperty());
    4197             : 
    4198             :     if (!list) {
    4199             :       list = new nsTArray<nsWeakPtr>();
    4200             :       SetProperty(PaintedPresShellsProperty(), list);
    4201             :     }
    4202             : 
    4203             :     return list;
    4204             :   }
    4205             : 
    4206             : protected:
    4207             :   /**
    4208             :    * Copies aRootElemWM to mWritingMode on 'this' and all its ancestors.
    4209             :    */
    4210             :   inline void PropagateRootElementWritingMode(mozilla::WritingMode aRootElemWM);
    4211             : 
    4212             :   void MarkInReflow() {
    4213             : #ifdef DEBUG_dbaron_off
    4214             :     // bug 81268
    4215             :     NS_ASSERTION(!(mState & NS_FRAME_IN_REFLOW), "frame is already in reflow");
    4216             : #endif
    4217             :     AddStateBits(NS_FRAME_IN_REFLOW);
    4218             :   }
    4219             : 
    4220             :   nsFrameState     mState;
    4221             : 
    4222             :   /**
    4223             :    * List of properties attached to the frame.
    4224             :    */
    4225             :   FrameProperties  mProperties;
    4226             : 
    4227             :   // When there is an overflow area only slightly larger than mRect,
    4228             :   // we store a set of four 1-byte deltas from the edges of mRect
    4229             :   // rather than allocating a whole separate rectangle property.
    4230             :   // Note that these are unsigned values, all measured "outwards"
    4231             :   // from the edges of mRect, so /mLeft/ and /mTop/ are reversed from
    4232             :   // our normal coordinate system.
    4233             :   // If mOverflow.mType == NS_FRAME_OVERFLOW_LARGE, then the
    4234             :   // delta values are not meaningful and the overflow area is stored
    4235             :   // as a separate rect property.
    4236             :   struct VisualDeltas {
    4237             :     uint8_t mLeft;
    4238             :     uint8_t mTop;
    4239             :     uint8_t mRight;
    4240             :     uint8_t mBottom;
    4241             :     bool operator==(const VisualDeltas& aOther) const
    4242             :     {
    4243             :       return mLeft == aOther.mLeft && mTop == aOther.mTop &&
    4244             :              mRight == aOther.mRight && mBottom == aOther.mBottom;
    4245             :     }
    4246             :     bool operator!=(const VisualDeltas& aOther) const
    4247             :     {
    4248             :       return !(*this == aOther);
    4249             :     }
    4250             :   };
    4251             :   union {
    4252             :     uint32_t     mType;
    4253             :     VisualDeltas mVisualDeltas;
    4254             :   } mOverflow;
    4255             : 
    4256             :   /** @see GetWritingMode() */
    4257             :   mozilla::WritingMode mWritingMode;
    4258             : 
    4259             :   /** The ClassID of the concrete class of this instance. */
    4260             :   ClassID mClass; // 1 byte
    4261             : 
    4262             :   bool mMayHaveRoundedCorners : 1;
    4263             : 
    4264             :   /**
    4265             :    * True iff this frame has one or more associated image requests.
    4266             :    * @see mozilla::css::ImageLoader.
    4267             :    */
    4268             :   bool mHasImageRequest : 1;
    4269             : 
    4270             :   /**
    4271             :    * True if this frame has a continuation that has a first-letter frame, or its
    4272             :    * placeholder, as a child.  In that case this frame has a blockframe ancestor
    4273             :    * that has the first-letter frame hanging off it in the
    4274             :    * nsContainerFrame::FirstLetterProperty() property.
    4275             :    */
    4276             :   bool mHasFirstLetterChild : 1;
    4277             : 
    4278             :   /**
    4279             :    * True if this frame's parent is a wrapper anonymous box (e.g. a table
    4280             :    * anonymous box as specified at
    4281             :    * <https://www.w3.org/TR/CSS21/tables.html#anonymous-boxes>).
    4282             :    *
    4283             :    * We could compute this information directly when we need it, but it wouldn't
    4284             :    * be all that cheap, and since this information is immutable for the lifetime
    4285             :    * of the frame we might as well cache it.
    4286             :    *
    4287             :    * Note that our parent may itself have mParentIsWrapperAnonBox set to true.
    4288             :    */
    4289             :   bool mParentIsWrapperAnonBox : 1;
    4290             : 
    4291             :   /**
    4292             :    * True if this is a wrapper anonymous box needing a restyle.  This is used to
    4293             :    * track, during stylo post-traversal, whether we've already recomputed the
    4294             :    * style of this anonymous box, if we end up seeing it twice.
    4295             :    */
    4296             :   bool mIsWrapperBoxNeedingRestyle : 1;
    4297             : 
    4298             :   /**
    4299             :    * This bit is used in nsTextFrame::CharacterDataChanged() as an optimization
    4300             :    * to skip redundant reflow-requests when the character data changes multiple
    4301             :    * times between reflows. If this flag is set, then it implies that the
    4302             :    * NS_FRAME_IS_DIRTY state bit is also set (and that intrinsic sizes have
    4303             :    * been marked as dirty on our ancestor chain).
    4304             :    *
    4305             :    * XXXdholbert This bit is *only* used on nsTextFrame, but it lives here on
    4306             :    * nsIFrame simply because this is where we've got unused state bits
    4307             :    * available in a gap. If bits become more scarce, we should perhaps consider
    4308             :    * expanding the range of frame-specific state bits in nsFrameStateBits.h and
    4309             :    * moving this to be one of those (e.g. by swapping one of the adjacent
    4310             :    * general-purpose bits to take the place of this bool:1 here, so we can grow
    4311             :    * that range of frame-specific bits by 1).
    4312             :    */
    4313             :   bool mReflowRequestedForCharDataChange : 1;
    4314             : 
    4315             :   /**
    4316             :    * This bit is used during BuildDisplayList to mark frames that need to
    4317             :    * have display items rebuilt. We will descend into them if they are
    4318             :    * currently visible, even if they don't intersect the dirty area.
    4319             :    */
    4320             :   bool mForceDescendIntoIfVisible : 1;
    4321             : 
    4322             :   /**
    4323             :    * True if we have built display items for this frame since
    4324             :    * the last call to CheckAndClearDisplayListState, false
    4325             :    * otherwise. Used for the reftest harness to verify minimal
    4326             :    * display list building.
    4327             :    */
    4328             :   bool mBuiltDisplayList : 1;
    4329             : 
    4330             :   bool mFrameIsModified : 1;
    4331             : 
    4332             :   bool mHasOverrideDirtyRegion : 1;
    4333             : 
    4334             :   /**
    4335             :    * True if frame has will-change, and currently has display
    4336             :    * items consuming some of the will-change budget.
    4337             :    */
    4338             :   bool mMayHaveWillChangeBudget : 1;
    4339             : 
    4340             : private:
    4341             :   /**
    4342             :    * True if this is the primary frame for mContent.
    4343             :    */
    4344             :   bool mIsPrimaryFrame : 1;
    4345             : 
    4346             :   bool mMayHaveTransformAnimation : 1;
    4347             :   bool mMayHaveOpacityAnimation : 1;
    4348             : 
    4349             :   /**
    4350             :    * True if we are certain that all descendants are not visible.
    4351             :    *
    4352             :    * This flag is conservative in that it might sometimes be false even if, in
    4353             :    * fact, all descendants are invisible.
    4354             :    * For example; an element is visibility:visible and has a visibility:hidden
    4355             :    * child. This flag is stil false in such case.
    4356             :    */
    4357             :   bool mAllDescendantsAreInvisible : 1;
    4358             : 
    4359             : protected:
    4360             : 
    4361             :   // There is a 1-bit gap left here.
    4362             : 
    4363             :   // Helpers
    4364             :   /**
    4365             :    * Can we stop inside this frame when we're skipping non-rendered whitespace?
    4366             :    * @param  aForward [in] Are we moving forward (or backward) in content order.
    4367             :    * @param  aOffset [in/out] At what offset into the frame to start looking.
    4368             :    *         on output - what offset was reached (whether or not we found a place to stop).
    4369             :    * @return STOP: An appropriate offset was found within this frame,
    4370             :    *         and is given by aOffset.
    4371             :    *         CONTINUE: Not found within this frame, need to try the next frame.
    4372             :    *         see enum FrameSearchResult for more details.
    4373             :    */
    4374             :   virtual FrameSearchResult PeekOffsetNoAmount(bool aForward, int32_t* aOffset) = 0;
    4375             : 
    4376             :   /**
    4377             :    * Search the frame for the next character
    4378             :    * @param  aForward [in] Are we moving forward (or backward) in content order.
    4379             :    * @param  aOffset [in/out] At what offset into the frame to start looking.
    4380             :    *         on output - what offset was reached (whether or not we found a place to stop).
    4381             :    * @param  aOptions [in] Options, see the comment in
    4382             :    *         PeekOffsetCharacterOptions for the detail.
    4383             :    * @return STOP: An appropriate offset was found within this frame,
    4384             :    *         and is given by aOffset.
    4385             :    *         CONTINUE: Not found within this frame, need to try the next frame.
    4386             :    *         see enum FrameSearchResult for more details.
    4387             :    */
    4388             :   virtual FrameSearchResult
    4389             :   PeekOffsetCharacter(bool aForward, int32_t* aOffset,
    4390             :                       PeekOffsetCharacterOptions aOptions =
    4391             :                         PeekOffsetCharacterOptions()) = 0;
    4392             :   static_assert(sizeof(PeekOffsetCharacterOptions) <= sizeof(intptr_t),
    4393             :                 "aOptions should be changed to const reference");
    4394             : 
    4395             :   /**
    4396             :    * Search the frame for the next word boundary
    4397             :    * @param  aForward [in] Are we moving forward (or backward) in content order.
    4398             :    * @param  aWordSelectEatSpace [in] true: look for non-whitespace following
    4399             :    *         whitespace (in the direction of movement).
    4400             :    *         false: look for whitespace following non-whitespace (in the
    4401             :    *         direction  of movement).
    4402             :    * @param  aIsKeyboardSelect [in] Was the action initiated by a keyboard operation?
    4403             :    *         If true, punctuation immediately following a word is considered part
    4404             :    *         of that word. Otherwise, a sequence of punctuation is always considered
    4405             :    *         as a word on its own.
    4406             :    * @param  aOffset [in/out] At what offset into the frame to start looking.
    4407             :    *         on output - what offset was reached (whether or not we found a place to stop).
    4408             :    * @param  aState [in/out] the state that is carried from frame to frame
    4409             :    * @return true: An appropriate offset was found within this frame,
    4410             :    *         and is given by aOffset.
    4411             :    *         false: Not found within this frame, need to try the next frame.
    4412             :    */
    4413             :   struct PeekWordState {
    4414             :     // true when we're still at the start of the search, i.e., we can't return
    4415             :     // this point as a valid offset!
    4416             :     bool mAtStart;
    4417             :     // true when we've encountered at least one character of the pre-boundary type
    4418             :     // (whitespace if aWordSelectEatSpace is true, non-whitespace otherwise)
    4419             :     bool mSawBeforeType;
    4420             :     // true when the last character encountered was punctuation
    4421             :     bool mLastCharWasPunctuation;
    4422             :     // true when the last character encountered was whitespace
    4423             :     bool mLastCharWasWhitespace;
    4424             :     // true when we've seen non-punctuation since the last whitespace
    4425             :     bool mSeenNonPunctuationSinceWhitespace;
    4426             :     // text that's *before* the current frame when aForward is true, *after*
    4427             :     // the current frame when aForward is false. Only includes the text
    4428             :     // on the current line.
    4429             :     nsAutoString mContext;
    4430             : 
    4431             :     PeekWordState() : mAtStart(true), mSawBeforeType(false),
    4432             :         mLastCharWasPunctuation(false), mLastCharWasWhitespace(false),
    4433             :         mSeenNonPunctuationSinceWhitespace(false) {}
    4434             :     void SetSawBeforeType() { mSawBeforeType = true; }
    4435             :     void Update(bool aAfterPunctuation, bool aAfterWhitespace) {
    4436             :       mLastCharWasPunctuation = aAfterPunctuation;
    4437             :       mLastCharWasWhitespace = aAfterWhitespace;
    4438             :       if (aAfterWhitespace) {
    4439             :         mSeenNonPunctuationSinceWhitespace = false;
    4440             :       } else if (!aAfterPunctuation) {
    4441             :         mSeenNonPunctuationSinceWhitespace = true;
    4442             :       }
    4443             :       mAtStart = false;
    4444             :     }
    4445             :   };
    4446             :   virtual FrameSearchResult PeekOffsetWord(bool aForward, bool aWordSelectEatSpace, bool aIsKeyboardSelect,
    4447             :                                 int32_t* aOffset, PeekWordState* aState) = 0;
    4448             : 
    4449             :   /**
    4450             :    * Search for the first paragraph boundary before or after the given position
    4451             :    * @param  aPos See description in nsFrameSelection.h. The following fields are
    4452             :    *              used by this method:
    4453             :    *              Input: mDirection
    4454             :    *              Output: mResultContent, mContentOffset
    4455             :    */
    4456             :   nsresult PeekOffsetParagraph(nsPeekOffsetStruct *aPos);
    4457             : 
    4458             : private:
    4459             :   // Get a pointer to the overflow areas property attached to the frame.
    4460             :   nsOverflowAreas* GetOverflowAreasProperty() const {
    4461             :     MOZ_ASSERT(mOverflow.mType == NS_FRAME_OVERFLOW_LARGE);
    4462             :     nsOverflowAreas* overflow = GetProperty(OverflowAreasProperty());
    4463             :     MOZ_ASSERT(overflow);
    4464             :     return overflow;
    4465             :   }
    4466             : 
    4467             :   nsRect GetVisualOverflowFromDeltas() const {
    4468             :     MOZ_ASSERT(mOverflow.mType != NS_FRAME_OVERFLOW_LARGE,
    4469             :                "should not be called when overflow is in a property");
    4470             :     // Calculate the rect using deltas from the frame's border rect.
    4471             :     // Note that the mOverflow.mDeltas fields are unsigned, but we will often
    4472             :     // need to return negative values for the left and top, so take care
    4473             :     // to cast away the unsigned-ness.
    4474             :     return nsRect(-(int32_t)mOverflow.mVisualDeltas.mLeft,
    4475             :                   -(int32_t)mOverflow.mVisualDeltas.mTop,
    4476             :                   mRect.Width() + mOverflow.mVisualDeltas.mRight +
    4477             :                                   mOverflow.mVisualDeltas.mLeft,
    4478             :                   mRect.Height() + mOverflow.mVisualDeltas.mBottom +
    4479             :                                    mOverflow.mVisualDeltas.mTop);
    4480             :   }
    4481             :   /**
    4482             :    * Returns true if any overflow changed.
    4483             :    */
    4484             :   bool SetOverflowAreas(const nsOverflowAreas& aOverflowAreas);
    4485             : 
    4486             :   // Helper-functions for SortFrameList():
    4487             :   template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
    4488             :   static nsIFrame* SortedMerge(nsIFrame *aLeft, nsIFrame *aRight);
    4489             : 
    4490             :   template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
    4491             :   static nsIFrame* MergeSort(nsIFrame *aSource);
    4492             : 
    4493             :   bool HasOpacityInternal(float aThreshold,
    4494             :                           mozilla::EffectSet* aEffectSet = nullptr) const;
    4495             : 
    4496             :   // Maps mClass to LayoutFrameType.
    4497             :   static const mozilla::LayoutFrameType sLayoutFrameTypes[
    4498             : #define FRAME_ID(...) 1 +
    4499             : #define ABSTRACT_FRAME_ID(...)
    4500             : #include "nsFrameIdList.h"
    4501             : #undef FRAME_ID
    4502             : #undef ABSTRACT_FRAME_ID
    4503             :   0];
    4504             : 
    4505             :   enum FrameClassBits {
    4506             :     eFrameClassBitsNone        = 0x0,
    4507             :     eFrameClassBitsLeaf        = 0x1,
    4508             :     eFrameClassBitsDynamicLeaf = 0x2,
    4509             :   };
    4510             :   // Maps mClass to IsLeaf() flags.
    4511             :   static const FrameClassBits sFrameClassBits[
    4512             : #define FRAME_ID(...) 1 +
    4513             : #define ABSTRACT_FRAME_ID(...)
    4514             : #include "nsFrameIdList.h"
    4515             : #undef FRAME_ID
    4516             : #undef ABSTRACT_FRAME_ID
    4517             :   0];
    4518             : 
    4519             : #ifdef DEBUG_FRAME_DUMP
    4520             : public:
    4521             :   static void IndentBy(FILE* out, int32_t aIndent) {
    4522             :     while (--aIndent >= 0) fputs("  ", out);
    4523             :   }
    4524             :   void ListTag(FILE* out) const {
    4525             :     ListTag(out, this);
    4526             :   }
    4527             :   static void ListTag(FILE* out, const nsIFrame* aFrame) {
    4528             :     nsAutoCString t;
    4529             :     ListTag(t, aFrame);
    4530             :     fputs(t.get(), out);
    4531             :   }
    4532             :   static void ListTag(FILE* out, const nsFrameList& aFrameList) {
    4533             :     for (nsIFrame* frame : aFrameList) {
    4534             :       ListTag(out, frame);
    4535             :     }
    4536             :   }
    4537             :   void ListTag(nsACString& aTo) const;
    4538             :   nsAutoCString ListTag() const {
    4539             :     nsAutoCString tag;
    4540             :     ListTag(tag);
    4541             :     return tag;
    4542             :   }
    4543             :   static void ListTag(nsACString& aTo, const nsIFrame* aFrame);
    4544             :   void ListGeneric(nsACString& aTo, const char* aPrefix = "", uint32_t aFlags = 0) const;
    4545             :   enum {
    4546             :     TRAVERSE_SUBDOCUMENT_FRAMES = 0x01
    4547             :   };
    4548             :   virtual void List(FILE* out = stderr, const char* aPrefix = "", uint32_t aFlags = 0) const;
    4549             :   /**
    4550             :    * lists the frames beginning from the root frame
    4551             :    * - calls root frame's List(...)
    4552             :    */
    4553             :   static void RootFrameList(nsPresContext* aPresContext,
    4554             :                             FILE* out = stderr, const char* aPrefix = "");
    4555             :   virtual void DumpFrameTree() const;
    4556             :   void DumpFrameTreeLimited() const;
    4557             : 
    4558             :   virtual nsresult  GetFrameName(nsAString& aResult) const = 0;
    4559             : #endif
    4560             : };
    4561             : 
    4562             : //----------------------------------------------------------------------
    4563             : 
    4564             : /**
    4565             :  * AutoWeakFrame can be used to keep a reference to a nsIFrame in a safe way.
    4566             :  * Whenever an nsIFrame object is deleted, the AutoWeakFrames pointing
    4567             :  * to it will be cleared.  AutoWeakFrame is for variables on the stack or
    4568             :  * in static storage only, there is also a WeakFrame below for heap uses.
    4569             :  *
    4570             :  * Create AutoWeakFrame object when it is sure that nsIFrame object
    4571             :  * is alive and after some operations which may destroy the nsIFrame
    4572             :  * (for example any DOM modifications) use IsAlive() or GetFrame() methods to
    4573             :  * check whether it is safe to continue to use the nsIFrame object.
    4574             :  *
    4575             :  * @note The usage of this class should be kept to a minimum.
    4576             :  */
    4577             : class WeakFrame;
    4578             : class MOZ_NONHEAP_CLASS AutoWeakFrame
    4579             : {
    4580             : public:
    4581             :   explicit AutoWeakFrame()
    4582             :     : mPrev(nullptr), mFrame(nullptr) {}
    4583             : 
    4584             :   AutoWeakFrame(const AutoWeakFrame& aOther)
    4585             :     : mPrev(nullptr), mFrame(nullptr)
    4586             :   {
    4587             :     Init(aOther.GetFrame());
    4588             :   }
    4589             : 
    4590             :   MOZ_IMPLICIT AutoWeakFrame(const WeakFrame& aOther);
    4591             : 
    4592           0 :   MOZ_IMPLICIT AutoWeakFrame(nsIFrame* aFrame)
    4593           0 :     : mPrev(nullptr), mFrame(nullptr)
    4594             :   {
    4595           0 :     Init(aFrame);
    4596           0 :   }
    4597             : 
    4598             :   AutoWeakFrame& operator=(AutoWeakFrame& aOther) {
    4599             :     Init(aOther.GetFrame());
    4600             :     return *this;
    4601             :   }
    4602             : 
    4603             :   AutoWeakFrame& operator=(nsIFrame* aFrame) {
    4604             :     Init(aFrame);
    4605             :     return *this;
    4606             :   }
    4607             : 
    4608             :   nsIFrame* operator->()
    4609             :   {
    4610             :     return mFrame;
    4611             :   }
    4612             : 
    4613             :   operator nsIFrame*()
    4614             :   {
    4615             :     return mFrame;
    4616             :   }
    4617             : 
    4618           0 :   void Clear(nsIPresShell* aShell) {
    4619           0 :     if (aShell) {
    4620           0 :       aShell->RemoveAutoWeakFrame(this);
    4621             :     }
    4622           0 :     mFrame = nullptr;
    4623           0 :     mPrev = nullptr;
    4624           0 :   }
    4625             : 
    4626             :   bool IsAlive() { return !!mFrame; }
    4627             : 
    4628             :   nsIFrame* GetFrame() const { return mFrame; }
    4629             : 
    4630             :   AutoWeakFrame* GetPreviousWeakFrame() { return mPrev; }
    4631             : 
    4632             :   void SetPreviousWeakFrame(AutoWeakFrame* aPrev) { mPrev = aPrev; }
    4633             : 
    4634           0 :   ~AutoWeakFrame()
    4635           0 :   {
    4636           0 :     Clear(mFrame ? mFrame->PresContext()->GetPresShell() : nullptr);
    4637           0 :   }
    4638             : private:
    4639             :   // Not available for the heap!
    4640             :   void* operator new(size_t) = delete;
    4641             :   void* operator new[](size_t) = delete;
    4642             :   void operator delete(void*) = delete;
    4643             :   void operator delete[](void*) = delete;
    4644             : 
    4645             :   void Init(nsIFrame* aFrame);
    4646             : 
    4647             :   AutoWeakFrame*  mPrev;
    4648             :   nsIFrame*       mFrame;
    4649             : };
    4650             : 
    4651             : // Use nsIFrame's fast-path to avoid QueryFrame:
    4652             : inline do_QueryFrameHelper<nsIFrame>
    4653             : do_QueryFrame(AutoWeakFrame& s)
    4654             : {
    4655             :   return do_QueryFrameHelper<nsIFrame>(s.GetFrame());
    4656             : }
    4657             : 
    4658             : /**
    4659             :  * @see AutoWeakFrame
    4660             :  */
    4661             : class MOZ_HEAP_CLASS WeakFrame
    4662             : {
    4663             : public:
    4664             :   WeakFrame() : mFrame(nullptr) {}
    4665             : 
    4666             :   WeakFrame(const WeakFrame& aOther) : mFrame(nullptr)
    4667             :   {
    4668             :     Init(aOther.GetFrame());
    4669             :   }
    4670             : 
    4671             :   MOZ_IMPLICIT WeakFrame(const AutoWeakFrame& aOther) : mFrame(nullptr)
    4672             :   {
    4673             :     Init(aOther.GetFrame());
    4674             :   }
    4675             : 
    4676             :   MOZ_IMPLICIT WeakFrame(nsIFrame* aFrame) : mFrame(nullptr)
    4677             :   {
    4678             :     Init(aFrame);
    4679             :   }
    4680             : 
    4681           0 :   ~WeakFrame()
    4682           0 :   {
    4683           0 :     Clear(mFrame ? mFrame->PresContext()->GetPresShell() : nullptr);
    4684           0 :   }
    4685             : 
    4686             :   WeakFrame& operator=(WeakFrame& aOther) {
    4687             :     Init(aOther.GetFrame());
    4688             :     return *this;
    4689             :   }
    4690             : 
    4691             :   WeakFrame& operator=(nsIFrame* aFrame) {
    4692           0 :     Init(aFrame);
    4693             :     return *this;
    4694             :   }
    4695             : 
    4696             :   nsIFrame* operator->() { return mFrame; }
    4697             :   operator nsIFrame*() { return mFrame; }
    4698             : 
    4699           0 :   void Clear(nsIPresShell* aShell) {
    4700           0 :     if (aShell) {
    4701           0 :       aShell->RemoveWeakFrame(this);
    4702             :     }
    4703           0 :     mFrame = nullptr;
    4704           0 :   }
    4705             : 
    4706           0 :   bool IsAlive() { return !!mFrame; }
    4707           0 :   nsIFrame* GetFrame() const { return mFrame; }
    4708             : 
    4709             : private:
    4710             :   void Init(nsIFrame* aFrame);
    4711             : 
    4712             :   nsIFrame* mFrame;
    4713             : };
    4714             : 
    4715             : // Use nsIFrame's fast-path to avoid QueryFrame:
    4716             : inline do_QueryFrameHelper<nsIFrame>
    4717             : do_QueryFrame(WeakFrame& s)
    4718             : {
    4719             :   return do_QueryFrameHelper<nsIFrame>(s.GetFrame());
    4720             : }
    4721             : 
    4722             : inline bool
    4723             : nsFrameList::ContinueRemoveFrame(nsIFrame* aFrame)
    4724             : {
    4725             :   MOZ_ASSERT(!aFrame->GetPrevSibling() || !aFrame->GetNextSibling(),
    4726             :              "Forgot to call StartRemoveFrame?");
    4727             :   if (aFrame == mLastChild) {
    4728             :     MOZ_ASSERT(!aFrame->GetNextSibling(), "broken frame list");
    4729             :     nsIFrame* prevSibling = aFrame->GetPrevSibling();
    4730             :     if (!prevSibling) {
    4731             :       MOZ_ASSERT(aFrame == mFirstChild, "broken frame list");
    4732             :       mFirstChild = mLastChild = nullptr;
    4733             :       return true;
    4734             :     }
    4735             :     MOZ_ASSERT(prevSibling->GetNextSibling() == aFrame, "Broken frame linkage");
    4736             :     prevSibling->SetNextSibling(nullptr);
    4737             :     mLastChild = prevSibling;
    4738             :     return true;
    4739             :   }
    4740             :   if (aFrame == mFirstChild) {
    4741             :     MOZ_ASSERT(!aFrame->GetPrevSibling(), "broken frame list");
    4742             :     mFirstChild = aFrame->GetNextSibling();
    4743             :     aFrame->SetNextSibling(nullptr);
    4744             :     MOZ_ASSERT(mFirstChild, "broken frame list");
    4745             :     return true;
    4746             :   }
    4747             :   return false;
    4748             : }
    4749             : 
    4750             : inline bool
    4751             : nsFrameList::StartRemoveFrame(nsIFrame* aFrame)
    4752             : {
    4753             :   if (aFrame->GetPrevSibling() && aFrame->GetNextSibling()) {
    4754             :     UnhookFrameFromSiblings(aFrame);
    4755             :     return true;
    4756             :   }
    4757             :   return ContinueRemoveFrame(aFrame);
    4758             : }
    4759             : 
    4760             : inline void
    4761             : nsFrameList::Enumerator::Next()
    4762             : {
    4763             :   NS_ASSERTION(!AtEnd(), "Should have checked AtEnd()!");
    4764             :   mFrame = mFrame->GetNextSibling();
    4765             : }
    4766             : 
    4767             : inline
    4768             : nsFrameList::FrameLinkEnumerator::
    4769             : FrameLinkEnumerator(const nsFrameList& aList, nsIFrame* aPrevFrame)
    4770             :   : Enumerator(aList)
    4771             : {
    4772             :   mPrev = aPrevFrame;
    4773             :   mFrame = aPrevFrame ? aPrevFrame->GetNextSibling() : aList.FirstChild();
    4774             : }
    4775             : 
    4776             : inline void
    4777             : nsFrameList::FrameLinkEnumerator::Next()
    4778             : {
    4779             :   mPrev = mFrame;
    4780             :   Enumerator::Next();
    4781             : }
    4782             : 
    4783             : // Operators of nsFrameList::Iterator
    4784             : // ---------------------------------------------------
    4785             : 
    4786             : inline nsFrameList::Iterator&
    4787             : nsFrameList::Iterator::operator++()
    4788             : {
    4789             :   mCurrent = mCurrent->GetNextSibling();
    4790             :   return *this;
    4791             : }
    4792             : 
    4793             : inline nsFrameList::Iterator&
    4794             : nsFrameList::Iterator::operator--()
    4795             : {
    4796             :   if (!mCurrent) {
    4797             :     mCurrent = mList.LastChild();
    4798             :   } else {
    4799             :     mCurrent = mCurrent->GetPrevSibling();
    4800             :   }
    4801             :   return *this;
    4802             : }
    4803             : 
    4804             : // Helper-functions for nsIFrame::SortFrameList()
    4805             : // ---------------------------------------------------
    4806             : 
    4807             : template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
    4808             : /* static */ nsIFrame*
    4809             : nsIFrame::SortedMerge(nsIFrame *aLeft, nsIFrame *aRight)
    4810             : {
    4811             :   MOZ_ASSERT(aLeft && aRight, "SortedMerge must have non-empty lists");
    4812             : 
    4813             :   nsIFrame *result;
    4814             :   // Unroll first iteration to avoid null-check 'result' inside the loop.
    4815             :   if (IsLessThanOrEqual(aLeft, aRight)) {
    4816             :     result = aLeft;
    4817             :     aLeft = aLeft->GetNextSibling();
    4818             :     if (!aLeft) {
    4819             :       result->SetNextSibling(aRight);
    4820             :       return result;
    4821             :     }
    4822             :   }
    4823             :   else {
    4824             :     result = aRight;
    4825             :     aRight = aRight->GetNextSibling();
    4826             :     if (!aRight) {
    4827             :       result->SetNextSibling(aLeft);
    4828             :       return result;
    4829             :     }
    4830             :   }
    4831             : 
    4832             :   nsIFrame *last = result;
    4833             :   for (;;) {
    4834             :     if (IsLessThanOrEqual(aLeft, aRight)) {
    4835             :       last->SetNextSibling(aLeft);
    4836             :       last = aLeft;
    4837             :       aLeft = aLeft->GetNextSibling();
    4838             :       if (!aLeft) {
    4839             :         last->SetNextSibling(aRight);
    4840             :         return result;
    4841             :       }
    4842             :     }
    4843             :     else {
    4844             :       last->SetNextSibling(aRight);
    4845             :       last = aRight;
    4846             :       aRight = aRight->GetNextSibling();
    4847             :       if (!aRight) {
    4848             :         last->SetNextSibling(aLeft);
    4849             :         return result;
    4850             :       }
    4851             :     }
    4852             :   }
    4853             : }
    4854             : 
    4855             : template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
    4856             : /* static */ nsIFrame*
    4857             : nsIFrame::MergeSort(nsIFrame *aSource)
    4858             : {
    4859             :   MOZ_ASSERT(aSource, "MergeSort null arg");
    4860             : 
    4861             :   nsIFrame *sorted[32] = { nullptr };
    4862             :   nsIFrame **fill = &sorted[0];
    4863             :   nsIFrame **left;
    4864             :   nsIFrame *rest = aSource;
    4865             : 
    4866             :   do {
    4867             :     nsIFrame *current = rest;
    4868             :     rest = rest->GetNextSibling();
    4869             :     current->SetNextSibling(nullptr);
    4870             : 
    4871             :     // Merge it with sorted[0] if present; then merge the result with sorted[1] etc.
    4872             :     // sorted[0] is a list of length 1 (or nullptr).
    4873             :     // sorted[1] is a list of length 2 (or nullptr).
    4874             :     // sorted[2] is a list of length 4 (or nullptr). etc.
    4875             :     for (left = &sorted[0]; left != fill && *left; ++left) {
    4876             :       current = SortedMerge<IsLessThanOrEqual>(*left, current);
    4877             :       *left = nullptr;
    4878             :     }
    4879             : 
    4880             :     // Fill the empty slot that we couldn't merge with the last result.
    4881             :     *left = current;
    4882             : 
    4883             :     if (left == fill)
    4884             :       ++fill;
    4885             :   } while (rest);
    4886             : 
    4887             :   // Collect and merge the results.
    4888             :   nsIFrame *result = nullptr;
    4889             :   for (left = &sorted[0]; left != fill; ++left) {
    4890             :     if (*left) {
    4891             :       result = result ? SortedMerge<IsLessThanOrEqual>(*left, result) : *left;
    4892             :     }
    4893             :   }
    4894             :   return result;
    4895             : }
    4896             : 
    4897             : template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
    4898             : /* static */ void
    4899             : nsIFrame::SortFrameList(nsFrameList& aFrameList)
    4900             : {
    4901             :   nsIFrame* head = MergeSort<IsLessThanOrEqual>(aFrameList.FirstChild());
    4902             :   aFrameList = nsFrameList(head, nsLayoutUtils::GetLastSibling(head));
    4903             :   MOZ_ASSERT(IsFrameListSorted<IsLessThanOrEqual>(aFrameList),
    4904             :              "After we sort a frame list, it should be in sorted order...");
    4905             : }
    4906             : 
    4907             : template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
    4908             : /* static */ bool
    4909             : nsIFrame::IsFrameListSorted(nsFrameList& aFrameList)
    4910             : {
    4911             :   if (aFrameList.IsEmpty()) {
    4912             :     // empty lists are trivially sorted.
    4913             :     return true;
    4914             :   }
    4915             : 
    4916             :   // We'll walk through the list with two iterators, one trailing behind the
    4917             :   // other. The list is sorted IFF trailingIter <= iter, across the whole list.
    4918             :   nsFrameList::Enumerator trailingIter(aFrameList);
    4919             :   nsFrameList::Enumerator iter(aFrameList);
    4920             :   iter.Next(); // Skip |iter| past first frame. (List is nonempty, so we can.)
    4921             : 
    4922             :   // Now, advance the iterators in parallel, comparing each adjacent pair.
    4923             :   while (!iter.AtEnd()) {
    4924             :     MOZ_ASSERT(!trailingIter.AtEnd(), "trailing iter shouldn't finish first");
    4925             :     if (!IsLessThanOrEqual(trailingIter.get(), iter.get())) {
    4926             :       return false;
    4927             :     }
    4928             :     trailingIter.Next();
    4929             :     iter.Next();
    4930             :   }
    4931             : 
    4932             :   // We made it to the end without returning early, so the list is sorted.
    4933             :   return true;
    4934             : }
    4935             : 
    4936             : // Needs to be defined here rather than nsIFrameInlines.h, because it is used
    4937             : // within this header.
    4938             : nsPoint
    4939             : nsIFrame::GetNormalPosition(bool* aHasProperty) const
    4940             : {
    4941             :   nsPoint* normalPosition = GetProperty(NormalPositionProperty());
    4942             :   if (normalPosition) {
    4943             :     if (aHasProperty) {
    4944             :       *aHasProperty = true;
    4945             :     }
    4946             :     return *normalPosition;
    4947             :   }
    4948             :   if (aHasProperty) {
    4949             :     *aHasProperty = false;
    4950             :   }
    4951             :   return GetPosition();
    4952             : }
    4953             : 
    4954             : #endif /* nsIFrame_h___ */

Generated by: LCOV version 1.13-14-ga5dd952