layout/mathml/nsMathMLContainerFrame.h

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

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

mercurial