tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsMathMLContainerFrame.h (22499B)


      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 #ifndef nsMathMLContainerFrame_h___
      8 #define nsMathMLContainerFrame_h___
      9 
     10 #include "mozilla/Likely.h"
     11 #include "nsBlockFrame.h"
     12 #include "nsContainerFrame.h"
     13 #include "nsInlineFrame.h"
     14 #include "nsMathMLFrame.h"
     15 #include "nsMathMLOperators.h"
     16 
     17 namespace mozilla {
     18 class PresShell;
     19 }  // namespace mozilla
     20 
     21 /*
     22 * Base class for MathML container frames. It acts like an inferred
     23 * mrow. By default, this frame uses its Reflow() method to lay its
     24 * children horizontally and ensure that their baselines are aligned.
     25 * The Reflow() method relies upon Place() to position children.
     26 * By overloading Place() in derived classes, it is therefore possible
     27 * to position children in various customized ways.
     28 */
     29 
     30 // Options for the preferred size at which to stretch our stretchy children
     31 #define STRETCH_CONSIDER_ACTUAL_SIZE 0x00000001  // just use our current size
     32 #define STRETCH_CONSIDER_EMBELLISHMENTS \
     33  0x00000002  // size calculations include embellishments
     34 
     35 class nsMathMLContainerFrame : public nsContainerFrame, public nsMathMLFrame {
     36 public:
     37  nsMathMLContainerFrame(ComputedStyle* aStyle, nsPresContext* aPresContext,
     38                         ClassID aID)
     39      : nsContainerFrame(aStyle, aPresContext, aID) {}
     40 
     41  NS_DECL_QUERYFRAME_TARGET(nsMathMLContainerFrame)
     42  NS_DECL_QUERYFRAME
     43  NS_DECL_ABSTRACT_FRAME(nsMathMLContainerFrame)
     44 
     45  // --------------------------------------------------------------------------
     46  // Overloaded nsMathMLFrame methods -- see documentation in nsIMathMLFrame.h
     47 
     48  NS_IMETHOD
     49  Stretch(DrawTarget* aDrawTarget, nsStretchDirection aStretchDirection,
     50          nsBoundingMetrics& aContainerSize,
     51          ReflowOutput& aDesiredStretchSize) override;
     52 
     53  NS_IMETHOD
     54  UpdatePresentationDataFromChildAt(
     55      int32_t aFirstIndex, int32_t aLastIndex,
     56      MathMLPresentationFlags aFlagsValues,
     57      MathMLPresentationFlags aFlagsToUpdate) override {
     58    PropagatePresentationDataFromChildAt(this, aFirstIndex, aLastIndex,
     59                                         aFlagsValues, aFlagsToUpdate);
     60    return NS_OK;
     61  }
     62 
     63  // --------------------------------------------------------------------------
     64  // Overloaded nsContainerFrame methods -- see documentation in nsIFrame.h
     65 
     66  void AppendFrames(ChildListID aListID, nsFrameList&& aFrameList) override;
     67 
     68  void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
     69                    const nsLineList::iterator* aPrevFrameLine,
     70                    nsFrameList&& aFrameList) override;
     71 
     72  void RemoveFrame(DestroyContext&, ChildListID aListID,
     73                   nsIFrame* aOldFrame) override;
     74 
     75  nscoord IntrinsicISize(const mozilla::IntrinsicSizeInput& aInput,
     76                         mozilla::IntrinsicISizeType aType) override;
     77 
     78  /**
     79   * Return the intrinsic horizontal metrics of the frame's content area.
     80   */
     81  virtual void GetIntrinsicISizeMetrics(gfxContext* aRenderingContext,
     82                                        ReflowOutput& aDesiredSize);
     83 
     84  void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
     85              const ReflowInput& aReflowInput,
     86              nsReflowStatus& aStatus) override;
     87 
     88  void BuildDisplayList(nsDisplayListBuilder* aBuilder,
     89                        const nsDisplayListSet& aLists) override;
     90 
     91  bool ComputeCustomOverflow(mozilla::OverflowAreas& aOverflowAreas) override;
     92 
     93  void MarkIntrinsicISizesDirty() override;
     94 
     95  // Notification when an attribute is changed. The MathML module uses the
     96  // following paradigm:
     97  //
     98  // 1. If the MathML frame class doesn't have any cached automatic data that
     99  //    depends on the attribute:
    100  //    1a. If the attribute is taken into account for the layout of the class
    101  //    then, we reflow (e.g., this happens with mfrac@linethickness).
    102  //    2b. Otherwise, we don't force any reflow.
    103  //
    104  // 2. If the MathML frame class has cached automatic data that depends on
    105  //    the attribute:
    106  //    2a. If the automatic data to update resides only within the descendants,
    107  //        we just re-layout them using ReLayoutChildren(this);
    108  //        (e.g., this happens with <ms>).
    109  //    2b. If the automatic data to update affects us in some way, we ask our
    110  //        parent to re-layout its children using ReLayoutChildren(mParent);
    111  //        Therefore, there is an overhead here in that our siblings are
    112  //        re-laid too (e.g., this happens with <munder>, <mover>,
    113  //        <munderover>).
    114  // nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
    115  //                           AttrModType aModType) override;
    116 
    117  // helper function to apply mirroring to a horizontal coordinate, if needed.
    118  nscoord MirrorIfRTL(nscoord aParentWidth, nscoord aChildWidth,
    119                      nscoord aChildLeading) {
    120    return StyleVisibility()->mDirection == mozilla::StyleDirection::Rtl
    121               ? aParentWidth - aChildWidth - aChildLeading
    122               : aChildLeading;
    123  }
    124 
    125  // --------------------------------------------------------------------------
    126  // Additional methods
    127 
    128 protected:
    129  enum class PlaceFlag : uint8_t {
    130    // If MeasureOnly is set, compute your desired size using the information
    131    // from GetReflowAndBoundingMetricsFor. However, child frames or other
    132    // elements should not be repositioned.
    133    // If MeasureOnly is not set, reflow is finished. You should position all
    134    // your children, and return your desired size. You should now use
    135    // FinishReflowChild() on your children to complete post-reflow operations.
    136    MeasureOnly,
    137 
    138    // If IntrinsicSize is set, the function is actually used to determine
    139    // intrinsic size (and consequently MeasureOnly is expected to be set too).
    140    // - It will use nsMathMLChar::GetMaxWidth instead of nsMathMLChar::Stretch.
    141    // - It will use IntrinsicISizeOffsets() for padding/border/margin instead
    142    //   of GetUsedBorder/Padding/Margin().
    143    // - etc
    144    IntrinsicSize,
    145 
    146    // If IgnoreBorderPadding is set, the function will complete without
    147    // adding the border/padding around the math layout. This can be used for
    148    // elements like <msqrt> that first layout their children as an <mrow>,
    149    // place some radical symbol on top of them and finally add its
    150    // padding/border around that radical symbol.
    151    IgnoreBorderPadding,
    152 
    153    // If DoNotAdjustForWidthAndHeight is set, the function will complete
    154    // without setting the computed width and height after the math layout. This
    155    // can be used similarly to IgnoreBorderPadding above.
    156    DoNotAdjustForWidthAndHeight,
    157  };
    158  using PlaceFlags = mozilla::EnumSet<PlaceFlag>;
    159 
    160  /* Place :
    161   * This method is used to measure or position child frames and other
    162   * elements.  It may be called any number of times with MeasureOnly
    163   * true, and the final call of the Reflow process before
    164   * returning from Reflow() or Stretch() will have MeasureOnly false
    165   * to position the elements.
    166   *
    167   * IMPORTANT: This method uses GetReflowAndBoundingMetricsFor() which must
    168   * have been set up with SaveReflowAndBoundingMetricsFor().
    169   *
    170   * The Place() method will use this information to compute the desired size
    171   * of the frame.
    172   *
    173   * @param aFlags [in] Flags to indicate the way the Place method should
    174   *        behave. See document for PlaceFlag above.
    175   *
    176   * @param aDesiredSize [out] parameter where you should return your desired
    177   *        size and your ascent/descent info. Compute your desired size using
    178   *        the information from GetReflowAndBoundingMetricsFor, and include
    179   *        any space you want for border/padding in the desired size you
    180   *        return.
    181   */
    182  virtual void Place(DrawTarget* aDrawTarget, const PlaceFlags& aFlags,
    183                     ReflowOutput& aDesiredSize);
    184 
    185  // helper to re-sync the automatic data in our children and notify our parent
    186  // to reflow us when changes (e.g., append/insert/remove) happen in our child
    187  // list
    188  virtual nsresult ChildListChanged();
    189 
    190  // helper to get the preferred size that a container frame should use to fire
    191  // the stretch on its stretchy child frames.
    192  void GetPreferredStretchSize(DrawTarget* aDrawTarget, uint32_t aOptions,
    193                               nsStretchDirection aStretchDirection,
    194                               nsBoundingMetrics& aPreferredStretchSize);
    195 
    196  // helper used by mstyle, mphantom, mpadded and mrow in their implementation
    197  // of TransmitAutomaticData() to determine whether they are space-like.
    198  nsresult TransmitAutomaticDataForMrowLikeElement();
    199 
    200 public:
    201  /*
    202   * Helper to render the frame as a default mrow-like container when an error
    203   * (typically invalid markup) was encountered during reflow. Parameters are
    204   * the same as Place().
    205   */
    206  void PlaceAsMrow(DrawTarget* aDrawTarget, const PlaceFlags& aFlags,
    207                   ReflowOutput& aDesiredSize);
    208 
    209  /*
    210   * Helper to call ReportErrorToConsole for parse errors involving
    211   * attribute/value pairs.
    212   * @param aAttribute The attribute for which the parse error occured.
    213   * @param aValue The value for which the parse error occured.
    214   */
    215  nsresult ReportParseError(const char16_t* aAttribute, const char16_t* aValue);
    216 
    217  /*
    218   * Helper to call ReportErrorToConsole when certain tags
    219   * have more than the expected amount of children.
    220   */
    221  nsresult ReportChildCountError();
    222 
    223  /*
    224   * Helper to call ReportErrorToConsole when certain tags have
    225   * invalid child tags
    226   * @param aChildTag The tag which is forbidden in this context
    227   */
    228  nsresult ReportInvalidChildError(nsAtom* aChildTag);
    229 
    230  /*
    231   * Helper to call ReportToConsole when an error occurs.
    232   * @param aParams see nsContentUtils::ReportToConsole
    233   */
    234  nsresult ReportErrorToConsole(
    235      const char* aErrorMsgId,
    236      const nsTArray<nsString>& aParams = nsTArray<nsString>());
    237 
    238  // helper method to reflow a child frame. We are inline frames, and we don't
    239  // know our positions until reflow is finished. That's why we ask the
    240  // base method not to worry about our position.
    241  void ReflowChild(nsIFrame* aKidFrame, nsPresContext* aPresContext,
    242                   ReflowOutput& aDesiredSize, const ReflowInput& aReflowInput,
    243                   nsReflowStatus& aStatus);
    244 
    245  nsMargin GetBorderPaddingForPlace(const PlaceFlags& aFlags);
    246 
    247  struct WidthAndHeightForPlaceAdjustment {
    248    mozilla::Maybe<nscoord> width;
    249    mozilla::Maybe<nscoord> height;
    250  };
    251  WidthAndHeightForPlaceAdjustment GetWidthAndHeightForPlaceAdjustment(
    252      const PlaceFlags& aFlags);
    253 
    254  virtual bool IsMathContentBoxHorizontallyCentered() const { return false; }
    255  nscoord ApplyAdjustmentForWidthAndHeight(
    256      const PlaceFlags& aFlags, const WidthAndHeightForPlaceAdjustment& aSizes,
    257      ReflowOutput& aReflowOutput, nsBoundingMetrics& aBoundingMetrics);
    258 
    259 protected:
    260  // helper to add the inter-spacing when <math> is the immediate parent.
    261  // Since we don't (yet) handle the root <math> element ourselves, we need to
    262  // take special care of the inter-frame spacing on elements for which <math>
    263  // is the direct xml parent. This function will be repeatedly called from
    264  // left to right on the childframes of <math>, and by so doing it will
    265  // emulate the spacing that would have been done by a <mrow> container.
    266  // e.g., it fixes <math> <mi>f</mi> <mo>q</mo> <mi>f</mi> <mo>I</mo> </math>
    267  virtual nscoord FixInterFrameSpacing(ReflowOutput& aDesiredSize);
    268 
    269  // helper method to complete the post-reflow hook and ensure that embellished
    270  // operators don't terminate their Reflow without receiving a Stretch command.
    271  virtual nsresult FinalizeReflow(DrawTarget* aDrawTarget,
    272                                  ReflowOutput& aDesiredSize);
    273 
    274  // Record metrics of a child frame for recovery through the following method
    275  static void SaveReflowAndBoundingMetricsFor(
    276      nsIFrame* aFrame, const ReflowOutput& aReflowOutput,
    277      const nsBoundingMetrics& aBoundingMetrics);
    278 
    279  // helper method to facilitate getting the reflow and bounding metrics of a
    280  // child frame.  The argument aMathMLFrameType, when non null, will return
    281  // the 'type' of the frame, which is used to determine the inter-frame
    282  // spacing.
    283  // IMPORTANT: This function is only meant to be called in Place() methods as
    284  // the information is available only when set up with the above method
    285  // during Reflow/Stretch() and GetPrefISize().
    286  static void GetReflowAndBoundingMetricsFor(
    287      nsIFrame* aFrame, ReflowOutput& aReflowOutput,
    288      nsBoundingMetrics& aBoundingMetrics,
    289      MathMLFrameType* aMathMLFrameType = nullptr);
    290 
    291  // helper method to clear metrics saved with
    292  // SaveReflowAndBoundingMetricsFor() from all child frames.
    293  void ClearSavedChildMetrics();
    294 
    295  static nsMargin GetMarginForPlace(const PlaceFlags& aFlags, nsIFrame* aChild);
    296 
    297  static void InflateReflowAndBoundingMetrics(
    298      const nsMargin& aBorderPadding, ReflowOutput& aReflowOutput,
    299      nsBoundingMetrics& aBoundingMetrics);
    300 
    301  // helper to let the update of presentation data pass through
    302  // a subtree that may contain non-MathML container frames
    303  static void PropagatePresentationDataFor(
    304      nsIFrame* aFrame, MathMLPresentationFlags aFlagsValues,
    305      MathMLPresentationFlags aFlagsToUpdate);
    306 
    307 public:
    308  static void PropagatePresentationDataFromChildAt(
    309      nsIFrame* aParentFrame, int32_t aFirstChildIndex, int32_t aLastChildIndex,
    310      MathMLPresentationFlags aFlagsValues,
    311      MathMLPresentationFlags aFlagsToUpdate);
    312 
    313  // Sets flags on aFrame and all descendant frames
    314  static void PropagateFrameFlagFor(nsIFrame* aFrame, nsFrameState aFlags);
    315 
    316  // helper to let the rebuild of automatic data (presentation data
    317  // and embellishement data) walk through a subtree that may contain
    318  // non-MathML container frames. Note that this method re-builds the
    319  // automatic data in the children -- not in aParentFrame itself (except
    320  // for those particular operations that the parent frame may do in its
    321  // TransmitAutomaticData()). The reason it works this way is because
    322  // a container frame knows what it wants for its children, whereas children
    323  // have no clue who their parent is. For example, it is <mfrac> who knows
    324  // that its children have to be in scriptsizes, and has to transmit this
    325  // information to them. Hence, when changes occur in a child frame, the child
    326  // has to request the re-build from its parent. Unfortunately, the extra cost
    327  // for this is that it will re-sync in the siblings of the child as well.
    328  static void RebuildAutomaticDataForChildren(nsIFrame* aParentFrame);
    329 
    330  // helper to blow away the automatic data cached in a frame's subtree and
    331  // re-layout its subtree to reflect changes that may have happen. In the
    332  // event where aParentFrame isn't a MathML frame, it will first walk up to
    333  // the ancestor that is a MathML frame, and re-layout from there -- this is
    334  // to guarantee that automatic data will be rebuilt properly. Note that this
    335  // method re-builds the automatic data in the children -- not in the parent
    336  // frame itself (except for those particular operations that the parent frame
    337  // may do do its TransmitAutomaticData()). @see
    338  // RebuildAutomaticDataForChildren
    339  //
    340  // aBits are the bits to pass to FrameNeedsReflow() when we call it.
    341  static nsresult ReLayoutChildren(nsIFrame* aParentFrame);
    342 
    343 protected:
    344  // Helper method which positions child frames as an <mrow> on given baseline
    345  // y = aBaseline starting from x = aOffsetX, calling FinishReflowChild()
    346  // on the frames.
    347  void PositionRowChildFrames(nscoord aOffsetX, nscoord aBaseline);
    348 
    349  // A variant on FinishAndStoreOverflow() that uses the union of child
    350  // overflows, the frame bounds, and mBoundingMetrics to set and store the
    351  // overflow.
    352  void GatherAndStoreOverflow(ReflowOutput* aMetrics);
    353 
    354  /**
    355   * Recompute mIntrinsicISize if it's not already up to date.
    356   */
    357  void UpdateIntrinsicISize(gfxContext* aRenderingContext);
    358 
    359  nscoord mIntrinsicISize = NS_INTRINSIC_ISIZE_UNKNOWN;
    360 
    361  nscoord mBlockStartAscent = 0;
    362 
    363 private:
    364  class RowChildFrameIterator;
    365  friend class RowChildFrameIterator;
    366 };
    367 
    368 // --------------------------------------------------------------------------
    369 // Currently, to benefit from line-breaking inside the <math> element, <math> is
    370 // simply mapping to nsBlockFrame or nsInlineFrame.
    371 // A separate implemention needs to provide:
    372 // 1) line-breaking
    373 // 2) proper inter-frame spacing
    374 // 3) firing of Stretch() (in which case FinalizeReflow() would have to be
    375 //    cleaned)
    376 // Issues: If/when mathml becomes a pluggable component, the separation will be
    377 // needed.
    378 class nsMathMLmathBlockFrame final : public nsBlockFrame {
    379 public:
    380  NS_DECL_QUERYFRAME
    381  NS_DECL_FRAMEARENA_HELPERS(nsMathMLmathBlockFrame)
    382 
    383  friend nsContainerFrame* NS_NewMathMLmathBlockFrame(
    384      mozilla::PresShell* aPresShell, ComputedStyle* aStyle);
    385 
    386  // beware, mFrames is not set by nsBlockFrame
    387  // cannot use mFrames{.FirstChild()|.etc} since the block code doesn't set
    388  // mFrames
    389  void SetInitialChildList(ChildListID aListID,
    390                           nsFrameList&& aChildList) override {
    391    MOZ_ASSERT(aListID == mozilla::FrameChildListID::Principal,
    392               "unexpected frame list");
    393    nsBlockFrame::SetInitialChildList(aListID, std::move(aChildList));
    394    if (aListID == mozilla::FrameChildListID::Principal) {
    395      // re-resolve our subtree to set any mathml-expected data
    396      nsMathMLContainerFrame::RebuildAutomaticDataForChildren(this);
    397    }
    398  }
    399 
    400  void AppendFrames(ChildListID aListID, nsFrameList&& aFrameList) override {
    401    NS_ASSERTION(aListID == mozilla::FrameChildListID::Principal ||
    402                     aListID == mozilla::FrameChildListID::NoReflowPrincipal,
    403                 "unexpected frame list");
    404    nsBlockFrame::AppendFrames(aListID, std::move(aFrameList));
    405    if (MOZ_LIKELY(aListID == mozilla::FrameChildListID::Principal)) {
    406      nsMathMLContainerFrame::ReLayoutChildren(this);
    407    }
    408  }
    409 
    410  void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
    411                    const nsLineList::iterator* aPrevFrameLine,
    412                    nsFrameList&& aFrameList) override {
    413    NS_ASSERTION(aListID == mozilla::FrameChildListID::Principal ||
    414                     aListID == mozilla::FrameChildListID::NoReflowPrincipal,
    415                 "unexpected frame list");
    416    nsBlockFrame::InsertFrames(aListID, aPrevFrame, aPrevFrameLine,
    417                               std::move(aFrameList));
    418    if (MOZ_LIKELY(aListID == mozilla::FrameChildListID::Principal)) {
    419      nsMathMLContainerFrame::ReLayoutChildren(this);
    420    }
    421  }
    422 
    423  void RemoveFrame(DestroyContext& aContext, ChildListID aListID,
    424                   nsIFrame* aOldFrame) override {
    425    NS_ASSERTION(aListID == mozilla::FrameChildListID::Principal ||
    426                     aListID == mozilla::FrameChildListID::NoReflowPrincipal,
    427                 "unexpected frame list");
    428    nsBlockFrame::RemoveFrame(aContext, aListID, aOldFrame);
    429    if (MOZ_LIKELY(aListID == mozilla::FrameChildListID::Principal)) {
    430      nsMathMLContainerFrame::ReLayoutChildren(this);
    431    }
    432  }
    433 
    434  // See nsIMathMLFrame.h
    435  bool IsMrowLike() {
    436    return mFrames.FirstChild() != mFrames.LastChild() || !mFrames.FirstChild();
    437  }
    438 
    439 protected:
    440  explicit nsMathMLmathBlockFrame(ComputedStyle* aStyle,
    441                                  nsPresContext* aPresContext)
    442      : nsBlockFrame(aStyle, aPresContext, kClassID) {}
    443  virtual ~nsMathMLmathBlockFrame() = default;
    444 };
    445 
    446 // --------------
    447 
    448 class nsMathMLmathInlineFrame final : public nsInlineFrame,
    449                                      public nsMathMLFrame {
    450 public:
    451  NS_DECL_QUERYFRAME
    452  NS_DECL_FRAMEARENA_HELPERS(nsMathMLmathInlineFrame)
    453 
    454  friend nsContainerFrame* NS_NewMathMLmathInlineFrame(
    455      mozilla::PresShell* aPresShell, ComputedStyle* aStyle);
    456 
    457  void SetInitialChildList(ChildListID aListID,
    458                           nsFrameList&& aChildList) override {
    459    NS_ASSERTION(aListID == mozilla::FrameChildListID::Principal,
    460                 "unexpected frame list");
    461    nsInlineFrame::SetInitialChildList(aListID, std::move(aChildList));
    462    // re-resolve our subtree to set any mathml-expected data
    463    nsMathMLContainerFrame::RebuildAutomaticDataForChildren(this);
    464  }
    465 
    466  void AppendFrames(ChildListID aListID, nsFrameList&& aFrameList) override {
    467    NS_ASSERTION(aListID == mozilla::FrameChildListID::Principal ||
    468                     aListID == mozilla::FrameChildListID::NoReflowPrincipal,
    469                 "unexpected frame list");
    470    nsInlineFrame::AppendFrames(aListID, std::move(aFrameList));
    471    if (MOZ_LIKELY(aListID == mozilla::FrameChildListID::Principal)) {
    472      nsMathMLContainerFrame::ReLayoutChildren(this);
    473    }
    474  }
    475 
    476  void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
    477                    const nsLineList::iterator* aPrevFrameLine,
    478                    nsFrameList&& aFrameList) override {
    479    NS_ASSERTION(aListID == mozilla::FrameChildListID::Principal ||
    480                     aListID == mozilla::FrameChildListID::NoReflowPrincipal,
    481                 "unexpected frame list");
    482    nsInlineFrame::InsertFrames(aListID, aPrevFrame, aPrevFrameLine,
    483                                std::move(aFrameList));
    484    if (MOZ_LIKELY(aListID == mozilla::FrameChildListID::Principal)) {
    485      nsMathMLContainerFrame::ReLayoutChildren(this);
    486    }
    487  }
    488 
    489  void RemoveFrame(DestroyContext& aContext, ChildListID aListID,
    490                   nsIFrame* aOldFrame) override {
    491    NS_ASSERTION(aListID == mozilla::FrameChildListID::Principal ||
    492                     aListID == mozilla::FrameChildListID::NoReflowPrincipal,
    493                 "unexpected frame list");
    494    nsInlineFrame::RemoveFrame(aContext, aListID, aOldFrame);
    495    if (MOZ_LIKELY(aListID == mozilla::FrameChildListID::Principal)) {
    496      nsMathMLContainerFrame::ReLayoutChildren(this);
    497    }
    498  }
    499 
    500  bool IsMrowLike() override {
    501    return mFrames.FirstChild() != mFrames.LastChild() || !mFrames.FirstChild();
    502  }
    503 
    504 protected:
    505  explicit nsMathMLmathInlineFrame(ComputedStyle* aStyle,
    506                                   nsPresContext* aPresContext)
    507      : nsInlineFrame(aStyle, aPresContext, kClassID) {}
    508 
    509  virtual ~nsMathMLmathInlineFrame() = default;
    510 };
    511 
    512 #endif /* nsMathMLContainerFrame_h___ */