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