Bumping manifests a=b2g-bump
[gecko.git] / layout / forms / nsFieldSetFrame.cpp
blob0e0d279153cb2a172fd529859eeb803ab806486f
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/. */
6 #include "nsFieldSetFrame.h"
8 #include "mozilla/gfx/2D.h"
9 #include "nsCSSAnonBoxes.h"
10 #include "nsLayoutUtils.h"
11 #include "nsLegendFrame.h"
12 #include "nsCSSRendering.h"
13 #include <algorithm>
14 #include "nsIFrame.h"
15 #include "nsPresContext.h"
16 #include "RestyleManager.h"
17 #include "nsGkAtoms.h"
18 #include "nsStyleConsts.h"
19 #include "nsDisplayList.h"
20 #include "nsRenderingContext.h"
21 #include "nsIScrollableFrame.h"
22 #include "mozilla/Likely.h"
23 #include "mozilla/Maybe.h"
25 using namespace mozilla;
26 using namespace mozilla::gfx;
27 using namespace mozilla::image;
28 using namespace mozilla::layout;
30 nsContainerFrame*
31 NS_NewFieldSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
33 return new (aPresShell) nsFieldSetFrame(aContext);
36 NS_IMPL_FRAMEARENA_HELPERS(nsFieldSetFrame)
38 nsFieldSetFrame::nsFieldSetFrame(nsStyleContext* aContext)
39 : nsContainerFrame(aContext)
41 mLegendSpace = 0;
44 nsIAtom*
45 nsFieldSetFrame::GetType() const
47 return nsGkAtoms::fieldSetFrame;
50 nsRect
51 nsFieldSetFrame::VisualBorderRectRelativeToSelf() const
53 nscoord topBorder = StyleBorder()->GetComputedBorderWidth(NS_SIDE_TOP);
54 nsRect r(nsPoint(0,0), GetSize());
55 if (topBorder < mLegendRect.height) {
56 nscoord yoff = (mLegendRect.height - topBorder) / 2;
57 r.y += yoff;
58 r.height -= yoff;
60 return r;
63 nsIFrame*
64 nsFieldSetFrame::GetInner() const
66 nsIFrame* last = mFrames.LastChild();
67 if (last &&
68 last->StyleContext()->GetPseudo() == nsCSSAnonBoxes::fieldsetContent) {
69 return last;
71 MOZ_ASSERT(mFrames.LastChild() == mFrames.FirstChild());
72 return nullptr;
75 nsIFrame*
76 nsFieldSetFrame::GetLegend() const
78 if (mFrames.FirstChild() == GetInner()) {
79 MOZ_ASSERT(mFrames.LastChild() == mFrames.FirstChild());
80 return nullptr;
82 MOZ_ASSERT(mFrames.FirstChild() &&
83 mFrames.FirstChild()->GetContentInsertionFrame()->GetType() ==
84 nsGkAtoms::legendFrame);
85 return mFrames.FirstChild();
88 class nsDisplayFieldSetBorderBackground : public nsDisplayItem {
89 public:
90 nsDisplayFieldSetBorderBackground(nsDisplayListBuilder* aBuilder,
91 nsFieldSetFrame* aFrame)
92 : nsDisplayItem(aBuilder, aFrame) {
93 MOZ_COUNT_CTOR(nsDisplayFieldSetBorderBackground);
95 #ifdef NS_BUILD_REFCNT_LOGGING
96 virtual ~nsDisplayFieldSetBorderBackground() {
97 MOZ_COUNT_DTOR(nsDisplayFieldSetBorderBackground);
99 #endif
101 virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
102 HitTestState* aState,
103 nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
104 virtual void Paint(nsDisplayListBuilder* aBuilder,
105 nsRenderingContext* aCtx) MOZ_OVERRIDE;
106 virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
107 virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
108 const nsDisplayItemGeometry* aGeometry,
109 nsRegion *aInvalidRegion) MOZ_OVERRIDE;
110 NS_DISPLAY_DECL_NAME("FieldSetBorderBackground", TYPE_FIELDSET_BORDER_BACKGROUND)
113 void nsDisplayFieldSetBorderBackground::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
114 HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
116 // aPt is guaranteed to be in this item's bounds. We do the hit test based on the
117 // frame bounds even though our background doesn't cover the whole frame.
118 // It's not clear whether this is correct.
119 aOutFrames->AppendElement(mFrame);
122 void
123 nsDisplayFieldSetBorderBackground::Paint(nsDisplayListBuilder* aBuilder,
124 nsRenderingContext* aCtx)
126 DrawResult result = static_cast<nsFieldSetFrame*>(mFrame)->
127 PaintBorderBackground(*aCtx, ToReferenceFrame(),
128 mVisibleRect, aBuilder->GetBackgroundPaintFlags());
130 nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
133 nsDisplayItemGeometry*
134 nsDisplayFieldSetBorderBackground::AllocateGeometry(nsDisplayListBuilder* aBuilder)
136 return new nsDisplayItemGenericImageGeometry(this, aBuilder);
139 void
140 nsDisplayFieldSetBorderBackground::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
141 const nsDisplayItemGeometry* aGeometry,
142 nsRegion *aInvalidRegion)
144 auto geometry =
145 static_cast<const nsDisplayItemGenericImageGeometry*>(aGeometry);
147 if (aBuilder->ShouldSyncDecodeImages() &&
148 geometry->ShouldInvalidateToSyncDecodeImages()) {
149 bool snap;
150 aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
153 nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
156 void
157 nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
158 const nsRect& aDirtyRect,
159 const nsDisplayListSet& aLists) {
160 // Paint our background and border in a special way.
161 // REVIEW: We don't really need to check frame emptiness here; if it's empty,
162 // the background/border display item won't do anything, and if it isn't empty,
163 // we need to paint the outline
164 if (!(GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) &&
165 IsVisibleForPainting(aBuilder)) {
166 if (StyleBorder()->mBoxShadow) {
167 aLists.BorderBackground()->AppendNewToTop(new (aBuilder)
168 nsDisplayBoxShadowOuter(aBuilder, this));
171 // don't bother checking to see if we really have a border or background.
172 // we usually will have a border.
173 aLists.BorderBackground()->AppendNewToTop(new (aBuilder)
174 nsDisplayFieldSetBorderBackground(aBuilder, this));
176 DisplayOutlineUnconditional(aBuilder, aLists);
178 DO_GLOBAL_REFLOW_COUNT_DSP("nsFieldSetFrame");
181 if (GetPrevInFlow()) {
182 DisplayOverflowContainers(aBuilder, aDirtyRect, aLists);
185 nsDisplayListCollection contentDisplayItems;
186 if (nsIFrame* inner = GetInner()) {
187 // Collect the inner frame's display items into their own collection.
188 // We need to be calling BuildDisplayList on it before the legend in
189 // case it contains out-of-flow frames whose placeholders are in the
190 // legend. However, we want the inner frame's display items to be
191 // after the legend's display items in z-order, so we need to save them
192 // and append them later.
193 BuildDisplayListForChild(aBuilder, inner, aDirtyRect, contentDisplayItems);
195 if (nsIFrame* legend = GetLegend()) {
196 // The legend's background goes on our BlockBorderBackgrounds list because
197 // it's a block child.
198 nsDisplayListSet set(aLists, aLists.BlockBorderBackgrounds());
199 BuildDisplayListForChild(aBuilder, legend, aDirtyRect, set);
201 // Put the inner frame's display items on the master list. Note that this
202 // moves its border/background display items to our BorderBackground() list,
203 // which isn't really correct, but it's OK because the inner frame is
204 // anonymous and can't have its own border and background.
205 contentDisplayItems.MoveTo(aLists);
208 DrawResult
209 nsFieldSetFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext,
210 nsPoint aPt, const nsRect& aDirtyRect, uint32_t aBGFlags)
212 // if the border is smaller than the legend. Move the border down
213 // to be centered on the legend.
214 // FIXME: This means border-radius clamping is incorrect; we should
215 // override nsIFrame::GetBorderRadii.
216 nsRect rect = VisualBorderRectRelativeToSelf();
217 nscoord yoff = rect.y;
218 rect += aPt;
219 nsPresContext* presContext = PresContext();
221 DrawResult result =
222 nsCSSRendering::PaintBackground(presContext, aRenderingContext, this,
223 aDirtyRect, rect, aBGFlags);
225 nsCSSRendering::PaintBoxShadowInner(presContext, aRenderingContext,
226 this, rect, aDirtyRect);
228 if (nsIFrame* legend = GetLegend()) {
229 nscoord topBorder = StyleBorder()->GetComputedBorderWidth(NS_SIDE_TOP);
231 // Use the rect of the legend frame, not mLegendRect, so we draw our
232 // border under the legend's left and right margins.
233 nsRect legendRect = legend->GetRect() + aPt;
235 // we should probably use PaintBorderEdges to do this but for now just use clipping
236 // to achieve the same effect.
238 // draw left side
239 nsRect clipRect(rect);
240 clipRect.width = legendRect.x - rect.x;
241 clipRect.height = topBorder;
243 DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
244 gfxContext* gfx = aRenderingContext.ThebesContext();
245 int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
247 gfx->Save();
248 gfx->Clip(NSRectToSnappedRect(clipRect, appUnitsPerDevPixel, *drawTarget));
249 nsCSSRendering::PaintBorder(presContext, aRenderingContext, this,
250 aDirtyRect, rect, mStyleContext);
251 gfx->Restore();
254 // draw right side
255 clipRect = rect;
256 clipRect.x = legendRect.XMost();
257 clipRect.width = rect.XMost() - legendRect.XMost();
258 clipRect.height = topBorder;
260 gfx->Save();
261 gfx->Clip(NSRectToSnappedRect(clipRect, appUnitsPerDevPixel, *drawTarget));
262 nsCSSRendering::PaintBorder(presContext, aRenderingContext, this,
263 aDirtyRect, rect, mStyleContext);
264 gfx->Restore();
267 // draw bottom
268 clipRect = rect;
269 clipRect.y += topBorder;
270 clipRect.height = mRect.height - (yoff + topBorder);
272 gfx->Save();
273 gfx->Clip(NSRectToSnappedRect(clipRect, appUnitsPerDevPixel, *drawTarget));
274 nsCSSRendering::PaintBorder(presContext, aRenderingContext, this,
275 aDirtyRect, rect, mStyleContext);
276 gfx->Restore();
277 } else {
279 nsCSSRendering::PaintBorder(presContext, aRenderingContext, this,
280 aDirtyRect,
281 nsRect(aPt, mRect.Size()),
282 mStyleContext);
285 return result;
288 nscoord
289 nsFieldSetFrame::GetIntrinsicISize(nsRenderingContext* aRenderingContext,
290 nsLayoutUtils::IntrinsicISizeType aType)
292 nscoord legendWidth = 0;
293 nscoord contentWidth = 0;
294 if (nsIFrame* legend = GetLegend()) {
295 legendWidth =
296 nsLayoutUtils::IntrinsicForContainer(aRenderingContext, legend, aType);
299 if (nsIFrame* inner = GetInner()) {
300 // Ignore padding on the inner, since the padding will be applied to the
301 // outer instead, and the padding computed for the inner is wrong
302 // for percentage padding.
303 contentWidth =
304 nsLayoutUtils::IntrinsicForContainer(aRenderingContext, inner, aType,
305 nsLayoutUtils::IGNORE_PADDING);
308 return std::max(legendWidth, contentWidth);
312 nscoord
313 nsFieldSetFrame::GetMinISize(nsRenderingContext* aRenderingContext)
315 nscoord result = 0;
316 DISPLAY_MIN_WIDTH(this, result);
318 result = GetIntrinsicISize(aRenderingContext, nsLayoutUtils::MIN_ISIZE);
319 return result;
322 nscoord
323 nsFieldSetFrame::GetPrefISize(nsRenderingContext* aRenderingContext)
325 nscoord result = 0;
326 DISPLAY_PREF_WIDTH(this, result);
328 result = GetIntrinsicISize(aRenderingContext, nsLayoutUtils::PREF_ISIZE);
329 return result;
332 /* virtual */
333 LogicalSize
334 nsFieldSetFrame::ComputeSize(nsRenderingContext *aRenderingContext,
335 WritingMode aWM,
336 const LogicalSize& aCBSize,
337 nscoord aAvailableISize,
338 const LogicalSize& aMargin,
339 const LogicalSize& aBorder,
340 const LogicalSize& aPadding,
341 ComputeSizeFlags aFlags)
343 LogicalSize result =
344 nsContainerFrame::ComputeSize(aRenderingContext, aWM,
345 aCBSize, aAvailableISize,
346 aMargin, aBorder, aPadding, aFlags);
348 // XXX The code below doesn't make sense if the caller's writing mode
349 // is orthogonal to this frame's. Not sure yet what should happen then;
350 // for now, just bail out.
351 if (aWM.IsVertical() != GetWritingMode().IsVertical()) {
352 return result;
355 // Fieldsets never shrink below their min width.
357 // If we're a container for font size inflation, then shrink
358 // wrapping inside of us should not apply font size inflation.
359 AutoMaybeDisableFontInflation an(this);
361 nscoord minISize = GetMinISize(aRenderingContext);
362 if (minISize > result.ISize(aWM)) {
363 result.ISize(aWM) = minISize;
366 return result;
369 void
370 nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
371 nsHTMLReflowMetrics& aDesiredSize,
372 const nsHTMLReflowState& aReflowState,
373 nsReflowStatus& aStatus)
375 DO_GLOBAL_REFLOW_COUNT("nsFieldSetFrame");
376 DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
378 NS_PRECONDITION(aReflowState.ComputedWidth() != NS_INTRINSICSIZE,
379 "Should have a precomputed width!");
381 // Initialize OUT parameter
382 aStatus = NS_FRAME_COMPLETE;
384 nsOverflowAreas ocBounds;
385 nsReflowStatus ocStatus = NS_FRAME_COMPLETE;
386 if (GetPrevInFlow()) {
387 ReflowOverflowContainerChildren(aPresContext, aReflowState, ocBounds, 0,
388 ocStatus);
391 //------------ Handle Incremental Reflow -----------------
392 bool reflowInner;
393 bool reflowLegend;
394 nsIFrame* legend = GetLegend();
395 nsIFrame* inner = GetInner();
396 if (aReflowState.ShouldReflowAllKids()) {
397 reflowInner = inner != nullptr;
398 reflowLegend = legend != nullptr;
399 } else {
400 reflowInner = inner && NS_SUBTREE_DIRTY(inner);
401 reflowLegend = legend && NS_SUBTREE_DIRTY(legend);
404 // We don't allow fieldsets to break vertically. If we did, we'd
405 // need logic here to push and pull overflow frames.
406 // Since we're not applying our padding in this frame, we need to add it here
407 // to compute the available width for our children.
408 WritingMode innerWM = inner ? inner->GetWritingMode() : GetWritingMode();
409 WritingMode legendWM = legend ? legend->GetWritingMode() : GetWritingMode();
410 LogicalSize innerAvailSize = aReflowState.ComputedSizeWithPadding(innerWM);
411 LogicalSize legendAvailSize = aReflowState.ComputedSizeWithPadding(legendWM);
412 innerAvailSize.BSize(innerWM) = legendAvailSize.BSize(legendWM) =
413 NS_UNCONSTRAINEDSIZE;
414 NS_ASSERTION(!inner ||
415 nsLayoutUtils::IntrinsicForContainer(aReflowState.rendContext,
416 inner,
417 nsLayoutUtils::MIN_ISIZE) <=
418 innerAvailSize.ISize(innerWM),
419 "Bogus availSize.ISize; should be bigger");
420 NS_ASSERTION(!legend ||
421 nsLayoutUtils::IntrinsicForContainer(aReflowState.rendContext,
422 legend,
423 nsLayoutUtils::MIN_ISIZE) <=
424 legendAvailSize.ISize(legendWM),
425 "Bogus availSize.ISize; should be bigger");
427 // get our border and padding
428 nsMargin border = aReflowState.ComputedPhysicalBorderPadding() - aReflowState.ComputedPhysicalPadding();
430 // Figure out how big the legend is if there is one.
431 // get the legend's margin
432 nsMargin legendMargin(0,0,0,0);
433 // reflow the legend only if needed
434 Maybe<nsHTMLReflowState> legendReflowState;
435 if (legend) {
436 legendReflowState.emplace(aPresContext, aReflowState, legend,
437 legendAvailSize);
439 if (reflowLegend) {
440 nsHTMLReflowMetrics legendDesiredSize(aReflowState);
442 ReflowChild(legend, aPresContext, legendDesiredSize, *legendReflowState,
443 0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
444 #ifdef NOISY_REFLOW
445 printf(" returned (%d, %d)\n",
446 legendDesiredSize.Width(), legendDesiredSize.Height());
447 #endif
448 // figure out the legend's rectangle
449 legendMargin = legend->GetUsedMargin();
450 mLegendRect.width = legendDesiredSize.Width() + legendMargin.left + legendMargin.right;
451 mLegendRect.height = legendDesiredSize.Height() + legendMargin.top + legendMargin.bottom;
452 mLegendRect.x = 0;
453 mLegendRect.y = 0;
455 nscoord oldSpace = mLegendSpace;
456 mLegendSpace = 0;
457 if (mLegendRect.height > border.top) {
458 // center the border on the legend
459 mLegendSpace = mLegendRect.height - border.top;
460 } else {
461 mLegendRect.y = (border.top - mLegendRect.height)/2;
464 // if the legend space changes then we need to reflow the
465 // content area as well.
466 if (mLegendSpace != oldSpace && inner) {
467 reflowInner = true;
470 FinishReflowChild(legend, aPresContext, legendDesiredSize,
471 legendReflowState.ptr(), 0, 0, NS_FRAME_NO_MOVE_FRAME);
472 } else if (!legend) {
473 mLegendRect.SetEmpty();
474 mLegendSpace = 0;
475 } else {
476 // mLegendSpace and mLegendRect haven't changed, but we need
477 // the used margin when placing the legend.
478 legendMargin = legend->GetUsedMargin();
481 // reflow the content frame only if needed
482 if (reflowInner) {
483 nsHTMLReflowState kidReflowState(aPresContext, aReflowState, inner,
484 innerAvailSize, -1, -1,
485 nsHTMLReflowState::CALLER_WILL_INIT);
486 // Override computed padding, in case it's percentage padding
487 kidReflowState.Init(aPresContext, -1, -1, nullptr,
488 &aReflowState.ComputedPhysicalPadding());
489 // Our child is "height:100%" but we actually want its height to be reduced
490 // by the amount of content-height the legend is eating up, unless our
491 // height is unconstrained (in which case the child's will be too).
492 if (aReflowState.ComputedHeight() != NS_UNCONSTRAINEDSIZE) {
493 kidReflowState.SetComputedHeight(
494 std::max(0, aReflowState.ComputedHeight() - mLegendSpace));
497 if (aReflowState.ComputedMinHeight() > 0) {
498 kidReflowState.ComputedMinHeight() =
499 std::max(0, aReflowState.ComputedMinHeight() - mLegendSpace);
502 if (aReflowState.ComputedMaxHeight() != NS_UNCONSTRAINEDSIZE) {
503 kidReflowState.ComputedMaxHeight() =
504 std::max(0, aReflowState.ComputedMaxHeight() - mLegendSpace);
507 nsHTMLReflowMetrics kidDesiredSize(kidReflowState,
508 aDesiredSize.mFlags);
509 // Reflow the frame
510 NS_ASSERTION(kidReflowState.ComputedPhysicalMargin() == nsMargin(0,0,0,0),
511 "Margins on anonymous fieldset child not supported!");
512 nsPoint pt(border.left, border.top + mLegendSpace);
513 ReflowChild(inner, aPresContext, kidDesiredSize, kidReflowState,
514 pt.x, pt.y, 0, aStatus);
516 FinishReflowChild(inner, aPresContext, kidDesiredSize,
517 &kidReflowState, pt.x, pt.y, 0);
518 NS_FRAME_TRACE_REFLOW_OUT("FieldSet::Reflow", aStatus);
521 LogicalRect contentRect(innerWM);
522 if (inner) {
523 // We don't support margins on inner, so our content rect is just the
524 // inner's border-box.
525 contentRect = inner->GetLogicalRect(aReflowState.ComputedWidth());
528 // Our content rect must fill up the available width
529 if (innerAvailSize.ISize(innerWM) > contentRect.ISize(innerWM)) {
530 contentRect.ISize(innerWM) = innerAvailSize.ISize(innerWM);
533 //XXX temporary!
534 nsRect physicalContentRect =
535 contentRect.GetPhysicalRect(innerWM, aReflowState.ComputedWidth());
536 if (legend) {
537 // the legend is postioned horizontally within the inner's content rect
538 // (so that padding on the fieldset affects the legend position).
539 nsRect innerContentRect = physicalContentRect;
540 innerContentRect.Deflate(aReflowState.ComputedPhysicalPadding());
541 // if the inner content rect is larger than the legend, we can align the legend
542 if (innerContentRect.width > mLegendRect.width) {
543 int32_t align = static_cast<nsLegendFrame*>
544 (legend->GetContentInsertionFrame())->GetAlign();
546 switch (align) {
547 case NS_STYLE_TEXT_ALIGN_RIGHT:
548 mLegendRect.x = innerContentRect.XMost() - mLegendRect.width;
549 break;
550 case NS_STYLE_TEXT_ALIGN_CENTER:
551 // Note: rounding removed; there doesn't seem to be any need
552 mLegendRect.x = innerContentRect.width / 2 - mLegendRect.width / 2 + innerContentRect.x;
553 break;
554 default:
555 mLegendRect.x = innerContentRect.x;
556 break;
558 } else {
559 // otherwise make place for the legend
560 mLegendRect.x = innerContentRect.x;
561 innerContentRect.width = mLegendRect.width;
562 physicalContentRect.width = mLegendRect.width +
563 aReflowState.ComputedPhysicalPadding().LeftRight();
566 // place the legend
567 nsRect actualLegendRect(mLegendRect);
568 actualLegendRect.Deflate(legendMargin);
569 nsPoint actualLegendPos(actualLegendRect.TopLeft());
570 legendReflowState->ApplyRelativePositioning(&actualLegendPos);
571 legend->SetPosition(actualLegendPos);
572 nsContainerFrame::PositionFrameView(legend);
573 nsContainerFrame::PositionChildViews(legend);
576 // Return our size and our result.
577 WritingMode wm = aReflowState.GetWritingMode();
578 nsSize finalSize(physicalContentRect.width + border.LeftRight(),
579 mLegendSpace + border.TopBottom() +
580 (inner ? inner->GetRect().height : 0));
581 aDesiredSize.SetSize(wm, LogicalSize(wm, finalSize));
582 aDesiredSize.SetOverflowAreasToDesiredBounds();
583 if (legend)
584 ConsiderChildOverflow(aDesiredSize.mOverflowAreas, legend);
585 if (inner)
586 ConsiderChildOverflow(aDesiredSize.mOverflowAreas, inner);
588 // Merge overflow container bounds and status.
589 aDesiredSize.mOverflowAreas.UnionWith(ocBounds);
590 NS_MergeReflowStatusInto(&aStatus, ocStatus);
592 FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
594 InvalidateFrame();
596 NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
599 #ifdef DEBUG
600 void
601 nsFieldSetFrame::SetInitialChildList(ChildListID aListID,
602 nsFrameList& aChildList)
604 nsContainerFrame::SetInitialChildList(kPrincipalList, aChildList);
605 MOZ_ASSERT(GetInner());
607 void
608 nsFieldSetFrame::AppendFrames(ChildListID aListID,
609 nsFrameList& aFrameList)
611 MOZ_CRASH("nsFieldSetFrame::AppendFrames not supported");
614 void
615 nsFieldSetFrame::InsertFrames(ChildListID aListID,
616 nsIFrame* aPrevFrame,
617 nsFrameList& aFrameList)
619 MOZ_CRASH("nsFieldSetFrame::InsertFrames not supported");
622 void
623 nsFieldSetFrame::RemoveFrame(ChildListID aListID,
624 nsIFrame* aOldFrame)
626 MOZ_CRASH("nsFieldSetFrame::RemoveFrame not supported");
628 #endif
630 #ifdef ACCESSIBILITY
631 a11y::AccType
632 nsFieldSetFrame::AccessibleType()
634 return a11y::eHTMLGroupboxType;
636 #endif
638 nscoord
639 nsFieldSetFrame::GetLogicalBaseline(WritingMode aWritingMode) const
641 nsIFrame* inner = GetInner();
642 return inner->BStart(aWritingMode, GetParent()->GetSize().width) +
643 inner->GetLogicalBaseline(aWritingMode);