1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 // YY need to pass isMultiple before create called
40 //#include "nsFormControlFrame.h"
41 #include "nsHTMLContainerFrame.h"
42 #include "nsLegendFrame.h"
43 #include "nsIDOMNode.h"
44 #include "nsIDOMHTMLFieldSetElement.h"
45 #include "nsIDOMHTMLLegendElement.h"
46 #include "nsCSSRendering.h"
47 //#include "nsIDOMHTMLCollection.h"
48 #include "nsIContent.h"
50 #include "nsISupports.h"
52 #include "nsPresContext.h"
53 #include "nsFrameManager.h"
54 #include "nsHTMLParts.h"
55 #include "nsGkAtoms.h"
56 #include "nsStyleConsts.h"
60 #include "nsAccessibilityService.h"
62 #include "nsIServiceManager.h"
63 #include "nsDisplayList.h"
67 class nsFieldSetFrame
: public nsHTMLContainerFrame
{
69 NS_DECL_FRAMEARENA_HELPERS
71 nsFieldSetFrame(nsStyleContext
* aContext
);
73 NS_IMETHOD
SetInitialChildList(nsIAtom
* aListName
,
74 nsFrameList
& aChildList
);
77 GetIntrinsicWidth(nsIRenderingContext
* aRenderingContext
,
78 nsLayoutUtils::IntrinsicWidthType
);
79 virtual nscoord
GetMinWidth(nsIRenderingContext
* aRenderingContext
);
80 virtual nscoord
GetPrefWidth(nsIRenderingContext
* aRenderingContext
);
81 virtual nsSize
ComputeSize(nsIRenderingContext
*aRenderingContext
,
82 nsSize aCBSize
, nscoord aAvailableWidth
,
83 nsSize aMargin
, nsSize aBorder
, nsSize aPadding
,
85 virtual nscoord
GetBaseline() const;
87 NS_IMETHOD
Reflow(nsPresContext
* aPresContext
,
88 nsHTMLReflowMetrics
& aDesiredSize
,
89 const nsHTMLReflowState
& aReflowState
,
90 nsReflowStatus
& aStatus
);
92 NS_IMETHOD
BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
93 const nsRect
& aDirtyRect
,
94 const nsDisplayListSet
& aLists
);
96 void PaintBorderBackground(nsIRenderingContext
& aRenderingContext
,
97 nsPoint aPt
, const nsRect
& aDirtyRect
, PRUint32 aBGFlags
);
99 NS_IMETHOD
AppendFrames(nsIAtom
* aListName
,
100 nsFrameList
& aFrameList
);
101 NS_IMETHOD
InsertFrames(nsIAtom
* aListName
,
102 nsIFrame
* aPrevFrame
,
103 nsFrameList
& aFrameList
);
104 NS_IMETHOD
RemoveFrame(nsIAtom
* aListName
,
105 nsIFrame
* aOldFrame
);
107 virtual nsIAtom
* GetType() const;
108 virtual PRBool
IsContainingBlock() const;
111 virtual already_AddRefed
<nsAccessible
> CreateAccessible();
115 NS_IMETHOD
GetFrameName(nsAString
& aResult
) const {
116 return MakeFrameName(NS_LITERAL_STRING("FieldSet"), aResult
);
122 virtual PRIntn
GetSkipSides() const;
123 void ReparentFrameList(const nsFrameList
& aFrameList
);
125 nsIFrame
* mLegendFrame
;
126 nsIFrame
* mContentFrame
;
128 nscoord mLegendSpace
;
132 NS_NewFieldSetFrame(nsIPresShell
* aPresShell
, nsStyleContext
* aContext
)
134 return new (aPresShell
) nsFieldSetFrame(aContext
);
137 NS_IMPL_FRAMEARENA_HELPERS(nsFieldSetFrame
)
139 nsFieldSetFrame::nsFieldSetFrame(nsStyleContext
* aContext
)
140 : nsHTMLContainerFrame(aContext
)
142 mContentFrame
= nsnull
;
143 mLegendFrame
= nsnull
;
148 nsFieldSetFrame::GetType() const
150 return nsGkAtoms::fieldSetFrame
;
154 nsFieldSetFrame::IsContainingBlock() const
160 nsFieldSetFrame::SetInitialChildList(nsIAtom
* aListName
,
161 nsFrameList
& aChildList
)
163 // Get the content and legend frames.
164 if (!aChildList
.OnlyChild()) {
165 NS_ASSERTION(aChildList
.GetLength() == 2, "Unexpected child list");
166 mContentFrame
= aChildList
.LastChild();
167 mLegendFrame
= aChildList
.FirstChild();
169 mContentFrame
= aChildList
.FirstChild();
170 mLegendFrame
= nsnull
;
173 // Queue up the frames for the content frame
174 return nsHTMLContainerFrame::SetInitialChildList(nsnull
, aChildList
);
177 class nsDisplayFieldSetBorderBackground
: public nsDisplayItem
{
179 nsDisplayFieldSetBorderBackground(nsDisplayListBuilder
* aBuilder
,
180 nsFieldSetFrame
* aFrame
)
181 : nsDisplayItem(aBuilder
, aFrame
) {
182 MOZ_COUNT_CTOR(nsDisplayFieldSetBorderBackground
);
184 #ifdef NS_BUILD_REFCNT_LOGGING
185 virtual ~nsDisplayFieldSetBorderBackground() {
186 MOZ_COUNT_DTOR(nsDisplayFieldSetBorderBackground
);
190 virtual void HitTest(nsDisplayListBuilder
* aBuilder
, const nsRect
& aRect
,
191 HitTestState
* aState
, nsTArray
<nsIFrame
*> *aOutFrames
);
192 virtual void Paint(nsDisplayListBuilder
* aBuilder
,
193 nsIRenderingContext
* aCtx
);
194 NS_DISPLAY_DECL_NAME("FieldSetBorderBackground", TYPE_FIELDSET_BORDER_BACKGROUND
)
197 void nsDisplayFieldSetBorderBackground::HitTest(nsDisplayListBuilder
* aBuilder
, const nsRect
& aRect
,
198 HitTestState
* aState
, nsTArray
<nsIFrame
*> *aOutFrames
)
200 // aPt is guaranteed to be in this item's bounds. We do the hit test based on the
201 // frame bounds even though our background doesn't cover the whole frame.
202 // It's not clear whether this is correct.
203 aOutFrames
->AppendElement(mFrame
);
207 nsDisplayFieldSetBorderBackground::Paint(nsDisplayListBuilder
* aBuilder
,
208 nsIRenderingContext
* aCtx
)
210 static_cast<nsFieldSetFrame
*>(mFrame
)->
211 PaintBorderBackground(*aCtx
, ToReferenceFrame(),
212 mVisibleRect
, aBuilder
->GetBackgroundPaintFlags());
216 nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
217 const nsRect
& aDirtyRect
,
218 const nsDisplayListSet
& aLists
) {
219 // Paint our background and border in a special way.
220 // REVIEW: We don't really need to check frame emptiness here; if it's empty,
221 // the background/border display item won't do anything, and if it isn't empty,
222 // we need to paint the outline
223 if (IsVisibleForPainting(aBuilder
)) {
224 if (GetStyleBorder()->mBoxShadow
) {
225 nsresult rv
= aLists
.BorderBackground()->AppendNewToTop(new (aBuilder
)
226 nsDisplayBoxShadowOuter(aBuilder
, this));
227 NS_ENSURE_SUCCESS(rv
, rv
);
230 // don't bother checking to see if we really have a border or background.
231 // we usually will have a border.
232 nsresult rv
= aLists
.BorderBackground()->AppendNewToTop(new (aBuilder
)
233 nsDisplayFieldSetBorderBackground(aBuilder
, this));
234 NS_ENSURE_SUCCESS(rv
, rv
);
236 rv
= DisplayOutlineUnconditional(aBuilder
, aLists
);
237 NS_ENSURE_SUCCESS(rv
, rv
);
239 DO_GLOBAL_REFLOW_COUNT_DSP("nsFieldSetFrame");
242 nsDisplayListCollection contentDisplayItems
;
244 // Collect mContentFrame's display items into their own collection. We need
245 // to be calling BuildDisplayList on mContentFrame before mLegendFrame in
246 // case it contains out-of-flow frames whose placeholders are under
247 // mLegendFrame. However, we want mContentFrame's display items to be
248 // after mLegendFrame's display items in z-order, so we need to save them
249 // and append them later.
250 nsresult rv
= BuildDisplayListForChild(aBuilder
, mContentFrame
, aDirtyRect
,
251 contentDisplayItems
);
252 NS_ENSURE_SUCCESS(rv
, rv
);
255 // The legend's background goes on our BlockBorderBackgrounds list because
256 // it's a block child.
257 nsDisplayListSet
set(aLists
, aLists
.BlockBorderBackgrounds());
258 nsresult rv
= BuildDisplayListForChild(aBuilder
, mLegendFrame
, aDirtyRect
, set
);
259 NS_ENSURE_SUCCESS(rv
, rv
);
261 // Put mContentFrame's display items on the master list. Note that
262 // this moves mContentFrame's border/background display items to our
263 // BorderBackground() list, which isn't really correct, but it's OK because
264 // mContentFrame is anonymous and can't have its own border and background.
265 contentDisplayItems
.MoveTo(aLists
);
270 nsFieldSetFrame::PaintBorderBackground(nsIRenderingContext
& aRenderingContext
,
271 nsPoint aPt
, const nsRect
& aDirtyRect
, PRUint32 aBGFlags
)
273 PRIntn skipSides
= GetSkipSides();
274 const nsStyleBorder
* borderStyle
= GetStyleBorder();
276 nscoord topBorder
= borderStyle
->GetActualBorderWidth(NS_SIDE_TOP
);
278 nsPresContext
* presContext
= PresContext();
280 // if the border is smaller than the legend. Move the border down
281 // to be centered on the legend.
282 // FIXME: This means border-radius clamping is incorrect; we should
283 // override nsIFrame::GetBorderRadii.
284 if (topBorder
< mLegendRect
.height
)
285 yoff
= (mLegendRect
.height
- topBorder
)/2;
287 nsRect
rect(aPt
.x
, aPt
.y
+ yoff
, mRect
.width
, mRect
.height
- yoff
);
289 nsCSSRendering::PaintBackground(presContext
, aRenderingContext
, this,
290 aDirtyRect
, rect
, aBGFlags
);
292 nsCSSRendering::PaintBoxShadowInner(presContext
, aRenderingContext
,
293 this, rect
, aDirtyRect
);
297 // Use the rect of the legend frame, not mLegendRect, so we draw our
298 // border under the legend's left and right margins.
299 nsRect legendRect
= mLegendFrame
->GetRect() + aPt
;
301 // we should probably use PaintBorderEdges to do this but for now just use clipping
302 // to achieve the same effect.
305 nsRect
clipRect(rect
);
306 clipRect
.width
= legendRect
.x
- rect
.x
;
307 clipRect
.height
= topBorder
;
309 aRenderingContext
.PushState();
310 aRenderingContext
.SetClipRect(clipRect
, nsClipCombine_kIntersect
);
311 nsCSSRendering::PaintBorder(presContext
, aRenderingContext
, this,
312 aDirtyRect
, rect
, mStyleContext
, skipSides
);
314 aRenderingContext
.PopState();
319 clipRect
.x
= legendRect
.XMost();
320 clipRect
.width
= rect
.XMost() - legendRect
.XMost();
321 clipRect
.height
= topBorder
;
323 aRenderingContext
.PushState();
324 aRenderingContext
.SetClipRect(clipRect
, nsClipCombine_kIntersect
);
325 nsCSSRendering::PaintBorder(presContext
, aRenderingContext
, this,
326 aDirtyRect
, rect
, mStyleContext
, skipSides
);
328 aRenderingContext
.PopState();
333 clipRect
.y
+= topBorder
;
334 clipRect
.height
= mRect
.height
- (yoff
+ topBorder
);
336 aRenderingContext
.PushState();
337 aRenderingContext
.SetClipRect(clipRect
, nsClipCombine_kIntersect
);
338 nsCSSRendering::PaintBorder(presContext
, aRenderingContext
, this,
339 aDirtyRect
, rect
, mStyleContext
, skipSides
);
341 aRenderingContext
.PopState();
344 nsCSSRendering::PaintBorder(presContext
, aRenderingContext
, this,
346 nsRect(aPt
, mRect
.Size()),
347 mStyleContext
, skipSides
);
352 nsFieldSetFrame::GetIntrinsicWidth(nsIRenderingContext
* aRenderingContext
,
353 nsLayoutUtils::IntrinsicWidthType aType
)
355 nscoord legendWidth
= 0;
356 nscoord contentWidth
= 0;
359 nsLayoutUtils::IntrinsicForContainer(aRenderingContext
, mLegendFrame
,
365 nsLayoutUtils::IntrinsicForContainer(aRenderingContext
, mContentFrame
,
369 return NS_MAX(legendWidth
, contentWidth
);
374 nsFieldSetFrame::GetMinWidth(nsIRenderingContext
* aRenderingContext
)
377 DISPLAY_MIN_WIDTH(this, result
);
379 result
= GetIntrinsicWidth(aRenderingContext
, nsLayoutUtils::MIN_WIDTH
);
384 nsFieldSetFrame::GetPrefWidth(nsIRenderingContext
* aRenderingContext
)
387 DISPLAY_PREF_WIDTH(this, result
);
389 result
= GetIntrinsicWidth(aRenderingContext
, nsLayoutUtils::PREF_WIDTH
);
394 nsFieldSetFrame::ComputeSize(nsIRenderingContext
*aRenderingContext
,
395 nsSize aCBSize
, nscoord aAvailableWidth
,
396 nsSize aMargin
, nsSize aBorder
, nsSize aPadding
,
400 nsHTMLContainerFrame::ComputeSize(aRenderingContext
, aCBSize
,
402 aMargin
, aBorder
, aPadding
, aShrinkWrap
);
404 // Fieldsets never shrink below their min width.
405 nscoord minWidth
= GetMinWidth(aRenderingContext
);
406 if (minWidth
> result
.width
)
407 result
.width
= minWidth
;
413 nsFieldSetFrame::Reflow(nsPresContext
* aPresContext
,
414 nsHTMLReflowMetrics
& aDesiredSize
,
415 const nsHTMLReflowState
& aReflowState
,
416 nsReflowStatus
& aStatus
)
418 DO_GLOBAL_REFLOW_COUNT("nsFieldSetFrame");
419 DISPLAY_REFLOW(aPresContext
, this, aReflowState
, aDesiredSize
, aStatus
);
421 NS_PRECONDITION(aReflowState
.ComputedWidth() != NS_INTRINSICSIZE
,
422 "Should have a precomputed width!");
424 // Initialize OUT parameter
425 aStatus
= NS_FRAME_COMPLETE
;
427 //------------ Handle Incremental Reflow -----------------
428 PRBool reflowContent
;
431 if (aReflowState
.ShouldReflowAllKids()) {
432 reflowContent
= mContentFrame
!= nsnull
;
433 reflowLegend
= mLegendFrame
!= nsnull
;
435 reflowContent
= mContentFrame
&& NS_SUBTREE_DIRTY(mContentFrame
);
436 reflowLegend
= mLegendFrame
&& NS_SUBTREE_DIRTY(mLegendFrame
);
439 // We don't allow fieldsets to break vertically. If we did, we'd
440 // need logic here to push and pull overflow frames.
441 nsSize
availSize(aReflowState
.ComputedWidth(), NS_UNCONSTRAINEDSIZE
);
442 NS_ASSERTION(!mContentFrame
||
443 nsLayoutUtils::IntrinsicForContainer(aReflowState
.rendContext
,
445 nsLayoutUtils::MIN_WIDTH
) <=
447 "Bogus availSize.width; should be bigger");
448 NS_ASSERTION(!mLegendFrame
||
449 nsLayoutUtils::IntrinsicForContainer(aReflowState
.rendContext
,
451 nsLayoutUtils::MIN_WIDTH
) <=
453 "Bogus availSize.width; should be bigger");
455 // get our border and padding
456 const nsMargin
&borderPadding
= aReflowState
.mComputedBorderPadding
;
457 nsMargin border
= borderPadding
- aReflowState
.mComputedPadding
;
459 // Figure out how big the legend is if there is one.
460 // get the legend's margin
461 nsMargin
legendMargin(0,0,0,0);
462 // reflow the legend only if needed
464 nsHTMLReflowState
legendReflowState(aPresContext
, aReflowState
,
465 mLegendFrame
, availSize
);
467 nsHTMLReflowMetrics legendDesiredSize
;
469 ReflowChild(mLegendFrame
, aPresContext
, legendDesiredSize
, legendReflowState
,
470 0, 0, NS_FRAME_NO_MOVE_FRAME
, aStatus
);
472 printf(" returned (%d, %d)\n", legendDesiredSize
.width
, legendDesiredSize
.height
);
474 // figure out the legend's rectangle
475 legendMargin
= mLegendFrame
->GetUsedMargin();
476 mLegendRect
.width
= legendDesiredSize
.width
+ legendMargin
.left
+ legendMargin
.right
;
477 mLegendRect
.height
= legendDesiredSize
.height
+ legendMargin
.top
+ legendMargin
.bottom
;
478 mLegendRect
.x
= borderPadding
.left
;
481 nscoord oldSpace
= mLegendSpace
;
483 if (mLegendRect
.height
> border
.top
) {
484 // center the border on the legend
485 mLegendSpace
= mLegendRect
.height
- border
.top
;
487 mLegendRect
.y
= (border
.top
- mLegendRect
.height
)/2;
490 // if the legend space changes then we need to reflow the
491 // content area as well.
492 if (mLegendSpace
!= oldSpace
&& mContentFrame
) {
493 reflowContent
= PR_TRUE
;
496 FinishReflowChild(mLegendFrame
, aPresContext
, &legendReflowState
,
497 legendDesiredSize
, 0, 0, NS_FRAME_NO_MOVE_FRAME
);
498 } else if (!mLegendFrame
) {
502 // mLegendSpace and mLegendRect haven't changed, but we need
503 // the used margin when placing the legend.
504 legendMargin
= mLegendFrame
->GetUsedMargin();
507 // reflow the content frame only if needed
509 nsHTMLReflowState
kidReflowState(aPresContext
, aReflowState
, mContentFrame
,
511 // Our child is "height:100%" but we actually want its height to be reduced
512 // by the amount of content-height the legend is eating up, unless our
513 // height is unconstrained (in which case the child's will be too).
514 if (aReflowState
.ComputedHeight() != NS_UNCONSTRAINEDSIZE
) {
515 kidReflowState
.SetComputedHeight(NS_MAX(0, aReflowState
.ComputedHeight() - mLegendSpace
));
518 kidReflowState
.mComputedMinHeight
=
519 NS_MAX(0, aReflowState
.mComputedMinHeight
- mLegendSpace
);
521 if (aReflowState
.mComputedMaxHeight
!= NS_UNCONSTRAINEDSIZE
) {
522 kidReflowState
.mComputedMaxHeight
=
523 NS_MAX(0, aReflowState
.mComputedMaxHeight
- mLegendSpace
);
526 nsHTMLReflowMetrics
kidDesiredSize(aDesiredSize
.mFlags
);
528 NS_ASSERTION(kidReflowState
.mComputedMargin
== nsMargin(0,0,0,0),
529 "Margins on anonymous fieldset child not supported!");
530 nsPoint
pt(borderPadding
.left
, borderPadding
.top
+ mLegendSpace
);
531 ReflowChild(mContentFrame
, aPresContext
, kidDesiredSize
, kidReflowState
,
532 pt
.x
, pt
.y
, 0, aStatus
);
534 FinishReflowChild(mContentFrame
, aPresContext
, &kidReflowState
,
535 kidDesiredSize
, pt
.x
, pt
.y
, 0);
536 NS_FRAME_TRACE_REFLOW_OUT("FieldSet::Reflow", aStatus
);
539 nsRect
contentRect(0,0,0,0);
541 // We don't support margins on mContentFrame, so our "content rect" is just
543 contentRect
= mContentFrame
->GetRect();
546 // use the computed width if the inner content does not fill it
547 if (aReflowState
.ComputedWidth() > contentRect
.width
) {
548 contentRect
.width
= aReflowState
.ComputedWidth();
552 // if the content rect is larger then the legend we can align the legend
553 if (contentRect
.width
> mLegendRect
.width
) {
554 PRInt32 align
= static_cast<nsLegendFrame
*>(mLegendFrame
)->GetAlign();
557 case NS_STYLE_TEXT_ALIGN_RIGHT
:
558 mLegendRect
.x
= contentRect
.width
- mLegendRect
.width
+ borderPadding
.left
;
560 case NS_STYLE_TEXT_ALIGN_CENTER
:
561 // Note: rounding removed; there doesn't seem to be any need
562 mLegendRect
.x
= contentRect
.width
/ 2 - mLegendRect
.width
/ 2 + borderPadding
.left
;
567 // otherwise make place for the legend
568 contentRect
.width
= mLegendRect
.width
;
571 nsRect
actualLegendRect(mLegendRect
);
572 actualLegendRect
.Deflate(legendMargin
);
574 nsPoint curOrigin
= mLegendFrame
->GetPosition();
576 // only if the origin changed
577 if ((curOrigin
.x
!= mLegendRect
.x
) || (curOrigin
.y
!= mLegendRect
.y
)) {
578 mLegendFrame
->SetPosition(nsPoint(actualLegendRect
.x
, actualLegendRect
.y
));
579 nsContainerFrame::PositionFrameView(mLegendFrame
);
581 // We need to recursively process the legend frame's
582 // children since we're moving the frame after Reflow.
583 nsContainerFrame::PositionChildViews(mLegendFrame
);
587 // Return our size and our result
588 if (aReflowState
.ComputedHeight() == NS_INTRINSICSIZE
) {
589 aDesiredSize
.height
= mLegendSpace
+
590 borderPadding
.TopBottom() +
593 nscoord min
= borderPadding
.TopBottom() + mLegendRect
.height
;
594 aDesiredSize
.height
=
595 aReflowState
.ComputedHeight() + borderPadding
.TopBottom();
596 if (aDesiredSize
.height
< min
)
597 aDesiredSize
.height
= min
;
599 aDesiredSize
.width
= contentRect
.width
+ borderPadding
.LeftRight();
600 aDesiredSize
.SetOverflowAreasToDesiredBounds();
602 ConsiderChildOverflow(aDesiredSize
.mOverflowAreas
, mLegendFrame
);
604 ConsiderChildOverflow(aDesiredSize
.mOverflowAreas
, mContentFrame
);
605 FinishAndStoreOverflow(&aDesiredSize
);
607 Invalidate(aDesiredSize
.VisualOverflow());
609 NS_FRAME_SET_TRUNCATION(aStatus
, aReflowState
, aDesiredSize
);
614 nsFieldSetFrame::GetSkipSides() const
620 nsFieldSetFrame::AppendFrames(nsIAtom
* aListName
,
621 nsFrameList
& aFrameList
)
623 // aFrameList is not allowed to contain "the legend" for this fieldset
624 ReparentFrameList(aFrameList
);
625 return mContentFrame
->AppendFrames(aListName
, aFrameList
);
629 nsFieldSetFrame::InsertFrames(nsIAtom
* aListName
,
630 nsIFrame
* aPrevFrame
,
631 nsFrameList
& aFrameList
)
633 NS_ASSERTION(!aPrevFrame
|| aPrevFrame
->GetParent() == this ||
634 aPrevFrame
->GetParent() == mContentFrame
,
635 "inserting after sibling frame with different parent");
637 // aFrameList is not allowed to contain "the legend" for this fieldset
638 ReparentFrameList(aFrameList
);
639 if (NS_UNLIKELY(aPrevFrame
== mLegendFrame
)) {
642 return mContentFrame
->InsertFrames(aListName
, aPrevFrame
, aFrameList
);
646 nsFieldSetFrame::RemoveFrame(nsIAtom
* aListName
,
649 // For reference, see bug 70648, bug 276104 and bug 236071.
650 NS_ASSERTION(aOldFrame
!= mLegendFrame
, "Cannot remove mLegendFrame here");
651 return mContentFrame
->RemoveFrame(aListName
, aOldFrame
);
655 already_AddRefed
<nsAccessible
>
656 nsFieldSetFrame::CreateAccessible()
658 nsAccessibilityService
* accService
= nsIPresShell::AccService();
660 return accService
->CreateHTMLGroupboxAccessible(mContent
,
661 PresContext()->PresShell());
669 nsFieldSetFrame::ReparentFrameList(const nsFrameList
& aFrameList
)
671 nsFrameManager
* frameManager
= PresContext()->FrameManager();
672 for (nsFrameList::Enumerator
e(aFrameList
); !e
.AtEnd(); e
.Next()) {
673 NS_ASSERTION(mLegendFrame
|| e
.get()->GetType() != nsGkAtoms::legendFrame
,
674 "The fieldset's legend is not allowed in this list");
675 e
.get()->SetParent(mContentFrame
);
676 frameManager
->ReparentStyleContext(e
.get());
681 nsFieldSetFrame::GetBaseline() const
683 // We know mContentFrame is a block, so calling GetBaseline() on it will do
684 // the right thing (that being to return the baseline of the last line).
685 NS_ASSERTION(nsLayoutUtils::GetAsBlock(mContentFrame
),
686 "Unexpected mContentFrame");
687 return mContentFrame
->GetPosition().y
+ mContentFrame
->GetBaseline();