1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsBoxLayoutState.h"
9 #include "nsBoxFrame.h"
10 #include "nsDOMAttributeMap.h"
11 #include "nsPresContext.h"
13 #include "nsIContent.h"
14 #include "nsContainerFrame.h"
15 #include "nsNameSpaceManager.h"
16 #include "nsGkAtoms.h"
18 #include "nsIServiceManager.h"
19 #include "nsBoxLayout.h"
20 #include "FrameLayerBuilder.h"
21 #include "mozilla/dom/Attr.h"
22 #include "mozilla/dom/Element.h"
25 using namespace mozilla
;
27 nsresult
nsBox::BeginXULLayout(nsBoxLayoutState
& aState
) {
28 // mark ourselves as dirty so no child under us
29 // can post an incremental layout.
30 // XXXldb Is this still needed?
31 AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN
);
33 if (GetStateBits() & NS_FRAME_IS_DIRTY
) {
34 // If the parent is dirty, all the children are dirty (ReflowInput
37 for (box
= GetChildXULBox(this); box
; box
= GetNextXULBox(box
))
38 box
->AddStateBits(NS_FRAME_IS_DIRTY
);
41 // Another copy-over from ReflowInput.
42 // Since we are in reflow, we don't need to store these properties anymore.
43 DeleteProperty(UsedBorderProperty());
44 DeleteProperty(UsedPaddingProperty());
45 DeleteProperty(UsedMarginProperty());
51 nsBox::DoXULLayout(nsBoxLayoutState
& aState
) { return NS_OK
; }
53 nsresult
nsBox::EndXULLayout(nsBoxLayoutState
& aState
) {
54 return SyncLayout(aState
);
57 bool nsBox::gGotTheme
= false;
58 StaticRefPtr
<nsITheme
> nsBox::gTheme
;
60 nsBox::nsBox(ClassID aID
) : nsIFrame(aID
) {
61 MOZ_COUNT_CTOR(nsBox
);
63 gTheme
= do_GetNativeTheme();
71 // NOTE: This currently doesn't get called for |nsBoxToBlockAdaptor|
72 // objects, so don't rely on putting anything here.
73 MOZ_COUNT_DTOR(nsBox
);
76 /* static */ void nsBox::Shutdown() {
81 nsresult
nsBox::XULRelayoutChildAtOrdinal(nsIFrame
* aChild
) { return NS_OK
; }
83 nsresult
nsIFrame::GetXULClientRect(nsRect
& aClientRect
) {
85 aClientRect
.MoveTo(0, 0);
87 nsMargin borderPadding
;
88 GetXULBorderAndPadding(borderPadding
);
90 aClientRect
.Deflate(borderPadding
);
92 if (aClientRect
.width
< 0) aClientRect
.width
= 0;
94 if (aClientRect
.height
< 0) aClientRect
.height
= 0;
99 void nsBox::SetXULBounds(nsBoxLayoutState
& aState
, const nsRect
& aRect
,
100 bool aRemoveOverflowAreas
) {
103 uint32_t flags
= GetXULLayoutFlags();
105 uint32_t stateFlags
= aState
.LayoutFlags();
109 if ((flags
& NS_FRAME_NO_MOVE_FRAME
) == NS_FRAME_NO_MOVE_FRAME
)
110 SetSize(aRect
.Size());
114 // Nuke the overflow area. The caller is responsible for restoring
116 if (aRemoveOverflowAreas
) {
117 // remove the previously stored overflow area
118 ClearOverflowRects();
121 if (!(flags
& NS_FRAME_NO_MOVE_VIEW
)) {
122 nsContainerFrame::PositionFrameView(this);
123 if ((rect
.x
!= aRect
.x
) || (rect
.y
!= aRect
.y
))
124 nsContainerFrame::PositionChildViews(this);
128 nsresult
nsIFrame::GetXULBorderAndPadding(nsMargin
& aBorderAndPadding
) {
129 aBorderAndPadding
.SizeTo(0, 0, 0, 0);
130 nsresult rv
= GetXULBorder(aBorderAndPadding
);
131 if (NS_FAILED(rv
)) return rv
;
134 rv
= GetXULPadding(padding
);
135 if (NS_FAILED(rv
)) return rv
;
137 aBorderAndPadding
+= padding
;
142 nsresult
nsBox::GetXULBorder(nsMargin
& aMargin
) {
143 aMargin
.SizeTo(0, 0, 0, 0);
145 const nsStyleDisplay
* disp
= StyleDisplay();
146 if (disp
->HasAppearance() && gTheme
) {
147 // Go to the theme for the border.
148 nsPresContext
* context
= PresContext();
149 if (gTheme
->ThemeSupportsWidget(context
, this, disp
->mAppearance
)) {
150 LayoutDeviceIntMargin margin
= gTheme
->GetWidgetBorder(
151 context
->DeviceContext(), this, disp
->mAppearance
);
153 LayoutDevicePixel::ToAppUnits(margin
, context
->AppUnitsPerDevPixel());
158 aMargin
= StyleBorder()->GetComputedBorder();
163 nsresult
nsBox::GetXULPadding(nsMargin
& aPadding
) {
164 const nsStyleDisplay
* disp
= StyleDisplay();
165 if (disp
->HasAppearance() && gTheme
) {
166 // Go to the theme for the padding.
167 nsPresContext
* context
= PresContext();
168 if (gTheme
->ThemeSupportsWidget(context
, this, disp
->mAppearance
)) {
169 LayoutDeviceIntMargin padding
;
170 bool useThemePadding
= gTheme
->GetWidgetPadding(
171 context
->DeviceContext(), this, disp
->mAppearance
, &padding
);
172 if (useThemePadding
) {
173 aPadding
= LayoutDevicePixel::ToAppUnits(
174 padding
, context
->AppUnitsPerDevPixel());
180 aPadding
.SizeTo(0, 0, 0, 0);
181 StylePadding()->GetPadding(aPadding
);
186 nsresult
nsBox::GetXULMargin(nsMargin
& aMargin
) {
187 aMargin
.SizeTo(0, 0, 0, 0);
188 StyleMargin()->GetMargin(aMargin
);
193 void nsBox::SizeNeedsRecalc(nsSize
& aSize
) {
198 void nsBox::CoordNeedsRecalc(nscoord
& aFlex
) { aFlex
= -1; }
200 bool nsBox::DoesNeedRecalc(const nsSize
& aSize
) {
201 return (aSize
.width
== -1 || aSize
.height
== -1);
204 bool nsBox::DoesNeedRecalc(nscoord aCoord
) { return (aCoord
== -1); }
206 nsSize
nsBox::GetXULPrefSize(nsBoxLayoutState
& aState
) {
207 NS_ASSERTION(aState
.GetRenderingContext(), "must have rendering context");
210 DISPLAY_PREF_SIZE(this, pref
);
212 if (IsXULCollapsed()) return pref
;
214 AddBorderAndPadding(pref
);
215 bool widthSet
, heightSet
;
216 nsIFrame::AddXULPrefSize(this, pref
, widthSet
, heightSet
);
218 nsSize minSize
= GetXULMinSize(aState
);
219 nsSize maxSize
= GetXULMaxSize(aState
);
220 return BoundsCheck(minSize
, pref
, maxSize
);
223 nsSize
nsBox::GetXULMinSize(nsBoxLayoutState
& aState
) {
224 NS_ASSERTION(aState
.GetRenderingContext(), "must have rendering context");
227 DISPLAY_MIN_SIZE(this, min
);
229 if (IsXULCollapsed()) return min
;
231 AddBorderAndPadding(min
);
232 bool widthSet
, heightSet
;
233 nsIFrame::AddXULMinSize(aState
, this, min
, widthSet
, heightSet
);
237 nsSize
nsBox::GetXULMinSizeForScrollArea(nsBoxLayoutState
& aBoxLayoutState
) {
241 nsSize
nsBox::GetXULMaxSize(nsBoxLayoutState
& aState
) {
242 NS_ASSERTION(aState
.GetRenderingContext(), "must have rendering context");
244 nsSize
maxSize(NS_INTRINSICSIZE
, NS_INTRINSICSIZE
);
245 DISPLAY_MAX_SIZE(this, maxSize
);
247 if (IsXULCollapsed()) return maxSize
;
249 AddBorderAndPadding(maxSize
);
250 bool widthSet
, heightSet
;
251 nsIFrame::AddXULMaxSize(this, maxSize
, widthSet
, heightSet
);
255 nscoord
nsBox::GetXULFlex() {
258 nsIFrame::AddXULFlex(this, flex
);
263 uint32_t nsIFrame::GetXULOrdinal() {
264 uint32_t ordinal
= StyleXUL()->mBoxOrdinal
;
266 // When present, attribute value overrides CSS.
267 nsIContent
* content
= GetContent();
268 if (content
&& content
->IsXULElement()) {
272 content
->AsElement()->GetAttr(kNameSpaceID_None
, nsGkAtoms::ordinal
, value
);
273 if (!value
.IsEmpty()) {
274 ordinal
= value
.ToInteger(&error
);
281 nscoord
nsBox::GetXULBoxAscent(nsBoxLayoutState
& aState
) {
282 if (IsXULCollapsed()) return 0;
284 return GetXULPrefSize(aState
).height
;
287 bool nsBox::IsXULCollapsed() {
288 return StyleVisibility()->mVisible
== NS_STYLE_VISIBILITY_COLLAPSE
;
291 nsresult
nsIFrame::XULLayout(nsBoxLayoutState
& aState
) {
292 NS_ASSERTION(aState
.GetRenderingContext(), "must have rendering context");
294 nsBox
* box
= static_cast<nsBox
*>(this);
297 box
->BeginXULLayout(aState
);
299 box
->DoXULLayout(aState
);
301 box
->EndXULLayout(aState
);
306 bool nsBox::DoesClipChildren() {
307 const nsStyleDisplay
* display
= StyleDisplay();
309 (display
->mOverflowY
== StyleOverflow::MozHiddenUnscrollable
) ==
310 (display
->mOverflowX
== StyleOverflow::MozHiddenUnscrollable
),
311 "If one overflow is -moz-hidden-unscrollable, the other should be too");
312 return display
->mOverflowX
== StyleOverflow::MozHiddenUnscrollable
;
315 nsresult
nsBox::SyncLayout(nsBoxLayoutState
& aState
) {
317 if (IsXULCollapsed()) {
318 CollapseChild(aState, this, true);
323 if (GetStateBits() & NS_FRAME_IS_DIRTY
) XULRedraw(aState
);
325 RemoveStateBits(NS_FRAME_HAS_DIRTY_CHILDREN
| NS_FRAME_IS_DIRTY
|
326 NS_FRAME_FIRST_REFLOW
| NS_FRAME_IN_REFLOW
);
328 nsPresContext
* presContext
= aState
.PresContext();
330 uint32_t flags
= GetXULLayoutFlags();
332 uint32_t stateFlags
= aState
.LayoutFlags();
336 nsRect visualOverflow
;
338 if (ComputesOwnOverflowArea()) {
339 visualOverflow
= GetVisualOverflowRect();
341 nsRect
rect(nsPoint(0, 0), GetSize());
342 nsOverflowAreas
overflowAreas(rect
, rect
);
343 if (!DoesClipChildren() && !IsXULCollapsed()) {
344 // See if our child frames caused us to overflow after being laid
345 // out. If so, store the overflow area. This normally can't happen
346 // in XUL, but it can happen with the CSS 'outline' property and
347 // possibly with other exotic stuff (e.g. relatively positioned
348 // frames in HTML inside XUL).
349 nsLayoutUtils::UnionChildOverflow(this, overflowAreas
);
352 FinishAndStoreOverflow(overflowAreas
, GetSize());
353 visualOverflow
= overflowAreas
.VisualOverflow();
356 nsView
* view
= GetView();
358 // Make sure the frame's view is properly sized and positioned and has
359 // things like opacity correct
360 nsContainerFrame::SyncFrameViewAfterReflow(presContext
, this, view
,
361 visualOverflow
, flags
);
367 nsresult
nsIFrame::XULRedraw(nsBoxLayoutState
& aState
) {
368 if (aState
.PaintingDisabled()) return NS_OK
;
370 // nsStackLayout, at least, expects us to repaint descendants even
371 // if a damage rect is provided
372 InvalidateFrameSubtree();
377 bool nsIFrame::AddXULPrefSize(nsIFrame
* aBox
, nsSize
& aSize
, bool& aWidthSet
,
382 // add in the css min, max, pref
383 const nsStylePosition
* position
= aBox
->StylePosition();
385 // see if the width or height was specifically set
386 // XXX Handle eStyleUnit_Enumerated?
387 // (Handling the eStyleUnit_Enumerated types requires
388 // GetXULPrefSize/GetXULMinSize methods that don't consider
389 // (min-/max-/)(width/height) properties.)
390 const nsStyleCoord
& width
= position
->mWidth
;
391 if (width
.GetUnit() == eStyleUnit_Coord
) {
392 aSize
.width
= width
.GetCoordValue();
394 } else if (width
.IsCalcUnit()) {
395 if (!width
.CalcHasPercent()) {
396 // pass 0 for percentage basis since we know there are no %s
397 aSize
.width
= width
.ComputeComputedCalc(0);
398 if (aSize
.width
< 0) aSize
.width
= 0;
403 const nsStyleCoord
& height
= position
->mHeight
;
404 if (height
.GetUnit() == eStyleUnit_Coord
) {
405 aSize
.height
= height
.GetCoordValue();
407 } else if (height
.IsCalcUnit()) {
408 if (!height
.CalcHasPercent()) {
409 // pass 0 for percentage basis since we know there are no %s
410 aSize
.height
= height
.ComputeComputedCalc(0);
411 if (aSize
.height
< 0) aSize
.height
= 0;
416 nsIContent
* content
= aBox
->GetContent();
417 // ignore 'height' and 'width' attributes if the actual element is not XUL
418 // For example, we might be magic XUL frames whose primary content is an HTML
420 if (content
&& content
->IsXULElement()) {
424 content
->AsElement()->GetAttr(kNameSpaceID_None
, nsGkAtoms::width
, value
);
425 if (!value
.IsEmpty()) {
428 aSize
.width
= nsPresContext::CSSPixelsToAppUnits(value
.ToInteger(&error
));
432 content
->AsElement()->GetAttr(kNameSpaceID_None
, nsGkAtoms::height
, value
);
433 if (!value
.IsEmpty()) {
437 nsPresContext::CSSPixelsToAppUnits(value
.ToInteger(&error
));
442 return (aWidthSet
&& aHeightSet
);
445 // This returns the scrollbar width we want to use when either native
446 // theme is disabled, or the native theme claims that it doesn't support
448 static nscoord
GetScrollbarWidthNoTheme(nsIFrame
* aBox
) {
449 ComputedStyle
* scrollbarStyle
= nsLayoutUtils::StyleForScrollbar(aBox
);
450 switch (scrollbarStyle
->StyleUIReset()->mScrollbarWidth
) {
452 case StyleScrollbarWidth::Auto
:
453 return 12 * AppUnitsPerCSSPixel();
454 case StyleScrollbarWidth::Thin
:
455 return 6 * AppUnitsPerCSSPixel();
456 case StyleScrollbarWidth::None
:
461 bool nsIFrame::AddXULMinSize(nsBoxLayoutState
& aState
, nsIFrame
* aBox
,
462 nsSize
& aSize
, bool& aWidthSet
, bool& aHeightSet
) {
466 bool canOverride
= true;
468 // See if a native theme wants to supply a minimum size.
469 const nsStyleDisplay
* display
= aBox
->StyleDisplay();
470 if (display
->HasAppearance()) {
471 nsITheme
* theme
= aState
.PresContext()->GetTheme();
472 if (theme
&& theme
->ThemeSupportsWidget(aState
.PresContext(), aBox
,
473 display
->mAppearance
)) {
474 LayoutDeviceIntSize size
;
475 theme
->GetMinimumWidgetSize(aState
.PresContext(), aBox
,
476 display
->mAppearance
, &size
, &canOverride
);
478 aSize
.width
= aState
.PresContext()->DevPixelsToAppUnits(size
.width
);
482 aSize
.height
= aState
.PresContext()->DevPixelsToAppUnits(size
.height
);
486 switch (display
->mAppearance
) {
487 case StyleAppearance::ScrollbarVertical
:
488 aSize
.width
= GetScrollbarWidthNoTheme(aBox
);
491 case StyleAppearance::ScrollbarHorizontal
:
492 aSize
.height
= GetScrollbarWidthNoTheme(aBox
);
501 // add in the css min, max, pref
502 const nsStylePosition
* position
= aBox
->StylePosition();
504 // same for min size. Unfortunately min size is always set to 0. So for now
505 // we will assume 0 (as a coord) means not set.
506 const nsStyleCoord
& minWidth
= position
->mMinWidth
;
507 if ((minWidth
.GetUnit() == eStyleUnit_Coord
&&
508 minWidth
.GetCoordValue() != 0) ||
509 (minWidth
.IsCalcUnit() && !minWidth
.CalcHasPercent())) {
510 nscoord min
= minWidth
.ComputeCoordPercentCalc(0);
511 if (!aWidthSet
|| (min
> aSize
.width
&& canOverride
)) {
515 } else if (minWidth
.GetUnit() == eStyleUnit_Percent
) {
516 NS_ASSERTION(minWidth
.GetPercentValue() == 0.0f
,
517 "Non-zero percentage values not currently supported");
519 aWidthSet
= true; // FIXME: should we really do this for
522 // XXX Handle eStyleUnit_Enumerated?
523 // (Handling the eStyleUnit_Enumerated types requires
524 // GetXULPrefSize/GetXULMinSize methods that don't consider
525 // (min-/max-/)(width/height) properties.
526 // calc() with percentage is treated like '0' (unset)
528 const nsStyleCoord
& minHeight
= position
->mMinHeight
;
529 if ((minHeight
.GetUnit() == eStyleUnit_Coord
&&
530 minHeight
.GetCoordValue() != 0) ||
531 (minHeight
.IsCalcUnit() && !minHeight
.CalcHasPercent())) {
532 nscoord min
= minHeight
.ComputeCoordPercentCalc(0);
533 if (!aHeightSet
|| (min
> aSize
.height
&& canOverride
)) {
537 } else if (minHeight
.GetUnit() == eStyleUnit_Percent
) {
538 NS_ASSERTION(position
->mMinHeight
.GetPercentValue() == 0.0f
,
539 "Non-zero percentage values not currently supported");
541 aHeightSet
= true; // FIXME: should we really do this for
544 // calc() with percentage is treated like '0' (unset)
546 nsIContent
* content
= aBox
->GetContent();
547 if (content
&& content
->IsXULElement()) {
551 content
->AsElement()->GetAttr(kNameSpaceID_None
, nsGkAtoms::minwidth
,
553 if (!value
.IsEmpty()) {
556 nscoord val
= nsPresContext::CSSPixelsToAppUnits(value
.ToInteger(&error
));
557 if (val
> aSize
.width
) aSize
.width
= val
;
561 content
->AsElement()->GetAttr(kNameSpaceID_None
, nsGkAtoms::minheight
,
563 if (!value
.IsEmpty()) {
566 nscoord val
= nsPresContext::CSSPixelsToAppUnits(value
.ToInteger(&error
));
567 if (val
> aSize
.height
) aSize
.height
= val
;
573 return (aWidthSet
&& aHeightSet
);
576 bool nsIFrame::AddXULMaxSize(nsIFrame
* aBox
, nsSize
& aSize
, bool& aWidthSet
,
581 // add in the css min, max, pref
582 const nsStylePosition
* position
= aBox
->StylePosition();
585 // see if the width or height was specifically set
586 // XXX Handle eStyleUnit_Enumerated?
587 // (Handling the eStyleUnit_Enumerated types requires
588 // GetXULPrefSize/GetXULMinSize methods that don't consider
589 // (min-/max-/)(width/height) properties.)
590 const nsStyleCoord maxWidth
= position
->mMaxWidth
;
591 if (maxWidth
.ConvertsToLength()) {
592 aSize
.width
= maxWidth
.ComputeCoordPercentCalc(0);
595 // percentages and calc() with percentages are treated like 'none'
597 const nsStyleCoord
& maxHeight
= position
->mMaxHeight
;
598 if (maxHeight
.ConvertsToLength()) {
599 aSize
.height
= maxHeight
.ComputeCoordPercentCalc(0);
602 // percentages and calc() with percentages are treated like 'none'
604 nsIContent
* content
= aBox
->GetContent();
605 if (content
&& content
->IsXULElement()) {
609 content
->AsElement()->GetAttr(kNameSpaceID_None
, nsGkAtoms::maxwidth
,
611 if (!value
.IsEmpty()) {
614 nscoord val
= nsPresContext::CSSPixelsToAppUnits(value
.ToInteger(&error
));
619 content
->AsElement()->GetAttr(kNameSpaceID_None
, nsGkAtoms::maxheight
,
621 if (!value
.IsEmpty()) {
624 nscoord val
= nsPresContext::CSSPixelsToAppUnits(value
.ToInteger(&error
));
631 return (aWidthSet
|| aHeightSet
);
634 bool nsIFrame::AddXULFlex(nsIFrame
* aBox
, nscoord
& aFlex
) {
635 bool flexSet
= false;
637 // get the flexibility
638 aFlex
= aBox
->StyleXUL()->mBoxFlex
;
640 // attribute value overrides CSS
641 nsIContent
* content
= aBox
->GetContent();
642 if (content
&& content
->IsXULElement()) {
646 content
->AsElement()->GetAttr(kNameSpaceID_None
, nsGkAtoms::flex
, value
);
647 if (!value
.IsEmpty()) {
649 aFlex
= value
.ToInteger(&error
);
654 if (aFlex
< 0) aFlex
= 0;
655 if (aFlex
>= nscoord_MAX
) aFlex
= nscoord_MAX
- 1;
657 return flexSet
|| aFlex
> 0;
660 void nsBox::AddBorderAndPadding(nsSize
& aSize
) {
661 AddBorderAndPadding(this, aSize
);
664 void nsBox::AddBorderAndPadding(nsIFrame
* aBox
, nsSize
& aSize
) {
665 nsMargin
borderPadding(0, 0, 0, 0);
666 aBox
->GetXULBorderAndPadding(borderPadding
);
667 AddMargin(aSize
, borderPadding
);
670 void nsBox::AddMargin(nsIFrame
* aChild
, nsSize
& aSize
) {
671 nsMargin
margin(0, 0, 0, 0);
672 aChild
->GetXULMargin(margin
);
673 AddMargin(aSize
, margin
);
676 void nsBox::AddMargin(nsSize
& aSize
, const nsMargin
& aMargin
) {
677 if (aSize
.width
!= NS_INTRINSICSIZE
)
678 aSize
.width
+= aMargin
.left
+ aMargin
.right
;
680 if (aSize
.height
!= NS_INTRINSICSIZE
)
681 aSize
.height
+= aMargin
.top
+ aMargin
.bottom
;
684 nscoord
nsBox::BoundsCheck(nscoord aMin
, nscoord aPref
, nscoord aMax
) {
685 if (aPref
> aMax
) aPref
= aMax
;
687 if (aPref
< aMin
) aPref
= aMin
;
692 nsSize
nsBox::BoundsCheckMinMax(const nsSize
& aMinSize
,
693 const nsSize
& aMaxSize
) {
694 return nsSize(std::max(aMaxSize
.width
, aMinSize
.width
),
695 std::max(aMaxSize
.height
, aMinSize
.height
));
698 nsSize
nsBox::BoundsCheck(const nsSize
& aMinSize
, const nsSize
& aPrefSize
,
699 const nsSize
& aMaxSize
) {
701 BoundsCheck(aMinSize
.width
, aPrefSize
.width
, aMaxSize
.width
),
702 BoundsCheck(aMinSize
.height
, aPrefSize
.height
, aMaxSize
.height
));
705 /*static*/ nsIFrame
* nsBox::GetChildXULBox(const nsIFrame
* aFrame
) {
706 // box layout ends at box-wrapped frames, so don't allow these frames
707 // to report child boxes.
708 return aFrame
->IsXULBoxFrame() ? aFrame
->PrincipalChildList().FirstChild()
712 /*static*/ nsIFrame
* nsBox::GetNextXULBox(const nsIFrame
* aFrame
) {
713 return aFrame
->GetParent() && aFrame
->GetParent()->IsXULBoxFrame()
714 ? aFrame
->GetNextSibling()
718 /*static*/ nsIFrame
* nsBox::GetParentXULBox(const nsIFrame
* aFrame
) {
719 return aFrame
->GetParent() && aFrame
->GetParent()->IsXULBoxFrame()
720 ? aFrame
->GetParent()