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