From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- layout/xul/nsLeafBoxFrame.cpp | 390 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 390 insertions(+) create mode 100644 layout/xul/nsLeafBoxFrame.cpp (limited to 'layout/xul/nsLeafBoxFrame.cpp') diff --git a/layout/xul/nsLeafBoxFrame.cpp b/layout/xul/nsLeafBoxFrame.cpp new file mode 100644 index 000000000..6d1783c11 --- /dev/null +++ b/layout/xul/nsLeafBoxFrame.cpp @@ -0,0 +1,390 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// +// Eric Vaughan +// Netscape Communications +// +// See documentation in associated header file +// + +#include "nsLeafBoxFrame.h" +#include "nsBoxFrame.h" +#include "nsCOMPtr.h" +#include "nsGkAtoms.h" +#include "nsPresContext.h" +#include "nsStyleContext.h" +#include "nsIContent.h" +#include "nsNameSpaceManager.h" +#include "nsBoxLayoutState.h" +#include "nsWidgetsCID.h" +#include "nsViewManager.h" +#include "nsContainerFrame.h" +#include "nsDisplayList.h" +#include + +using namespace mozilla; + +// +// NS_NewLeafBoxFrame +// +// Creates a new Toolbar frame and returns it +// +nsIFrame* +NS_NewLeafBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) +{ + return new (aPresShell) nsLeafBoxFrame(aContext); +} + +NS_IMPL_FRAMEARENA_HELPERS(nsLeafBoxFrame) + +nsLeafBoxFrame::nsLeafBoxFrame(nsStyleContext* aContext) + : nsLeafFrame(aContext) +{ +} + +#ifdef DEBUG_LAYOUT +void +nsLeafBoxFrame::GetBoxName(nsAutoString& aName) +{ + GetFrameName(aName); +} +#endif + + +/** + * Initialize us. This is a good time to get the alignment of the box + */ +void +nsLeafBoxFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) +{ + nsLeafFrame::Init(aContent, aParent, aPrevInFlow); + + if (GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER) { + AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT); + } + + UpdateMouseThrough(); +} + +nsresult +nsLeafBoxFrame::AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) +{ + nsresult rv = nsLeafFrame::AttributeChanged(aNameSpaceID, aAttribute, + aModType); + + if (aAttribute == nsGkAtoms::mousethrough) + UpdateMouseThrough(); + + return rv; +} + +void nsLeafBoxFrame::UpdateMouseThrough() +{ + if (mContent) { + static nsIContent::AttrValuesArray strings[] = + {&nsGkAtoms::never, &nsGkAtoms::always, nullptr}; + switch (mContent->FindAttrValueIn(kNameSpaceID_None, + nsGkAtoms::mousethrough, + strings, eCaseMatters)) { + case 0: AddStateBits(NS_FRAME_MOUSE_THROUGH_NEVER); break; + case 1: AddStateBits(NS_FRAME_MOUSE_THROUGH_ALWAYS); break; + case 2: { + RemoveStateBits(NS_FRAME_MOUSE_THROUGH_ALWAYS); + RemoveStateBits(NS_FRAME_MOUSE_THROUGH_NEVER); + break; + } + } + } +} + +void +nsLeafBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) +{ + // REVIEW: GetFrameForPoint used to not report events for the background + // layer, whereas this code will put an event receiver for this frame in the + // BlockBorderBackground() list. But I don't see any need to preserve + // that anomalous behaviour. The important thing I'm preserving is that + // leaf boxes continue to receive events in the foreground layer. + DisplayBorderBackgroundOutline(aBuilder, aLists); + + if (!aBuilder->IsForEventDelivery() || !IsVisibleForPainting(aBuilder)) + return; + + aLists.Content()->AppendNewToTop(new (aBuilder) + nsDisplayEventReceiver(aBuilder, this)); +} + +/* virtual */ nscoord +nsLeafBoxFrame::GetMinISize(nsRenderingContext *aRenderingContext) +{ + nscoord result; + DISPLAY_MIN_WIDTH(this, result); + nsBoxLayoutState state(PresContext(), aRenderingContext); + + WritingMode wm = GetWritingMode(); + LogicalSize minSize(wm, GetXULMinSize(state)); + + // GetXULMinSize returns border-box size, and we want to return content + // inline-size. Since Reflow uses the reflow state's border and padding, we + // actually just want to subtract what GetXULMinSize added, which is the + // result of GetXULBorderAndPadding. + nsMargin bp; + GetXULBorderAndPadding(bp); + + result = minSize.ISize(wm) - LogicalMargin(wm, bp).IStartEnd(wm); + + return result; +} + +/* virtual */ nscoord +nsLeafBoxFrame::GetPrefISize(nsRenderingContext *aRenderingContext) +{ + nscoord result; + DISPLAY_PREF_WIDTH(this, result); + nsBoxLayoutState state(PresContext(), aRenderingContext); + + WritingMode wm = GetWritingMode(); + LogicalSize prefSize(wm, GetXULPrefSize(state)); + + // GetXULPrefSize returns border-box size, and we want to return content + // inline-size. Since Reflow uses the reflow state's border and padding, we + // actually just want to subtract what GetXULPrefSize added, which is the + // result of GetXULBorderAndPadding. + nsMargin bp; + GetXULBorderAndPadding(bp); + + result = prefSize.ISize(wm) - LogicalMargin(wm, bp).IStartEnd(wm); + + return result; +} + +nscoord +nsLeafBoxFrame::GetIntrinsicISize() +{ + // No intrinsic width + return 0; +} + +LogicalSize +nsLeafBoxFrame::ComputeAutoSize(nsRenderingContext* aRenderingContext, + WritingMode aWM, + const LogicalSize& aCBSize, + nscoord aAvailableISize, + const LogicalSize& aMargin, + const LogicalSize& aBorder, + const LogicalSize& aPadding, + ComputeSizeFlags aFlags) +{ + // Important: NOT calling our direct superclass here! + return nsFrame::ComputeAutoSize(aRenderingContext, aWM, + aCBSize, aAvailableISize, + aMargin, aBorder, aPadding, aFlags); +} + +void +nsLeafBoxFrame::Reflow(nsPresContext* aPresContext, + ReflowOutput& aDesiredSize, + const ReflowInput& aReflowInput, + nsReflowStatus& aStatus) +{ + // This is mostly a copy of nsBoxFrame::Reflow(). + // We aren't able to share an implementation because of the frame + // class hierarchy. If you make changes here, please keep + // nsBoxFrame::Reflow in sync. + + MarkInReflow(); + DO_GLOBAL_REFLOW_COUNT("nsLeafBoxFrame"); + DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); + + NS_ASSERTION(aReflowInput.ComputedWidth() >=0 && + aReflowInput.ComputedHeight() >= 0, "Computed Size < 0"); + +#ifdef DO_NOISY_REFLOW + printf("\n-------------Starting LeafBoxFrame Reflow ----------------------------\n"); + printf("%p ** nsLBF::Reflow %d R: ", this, myCounter++); + switch (aReflowInput.reason) { + case eReflowReason_Initial: + printf("Ini");break; + case eReflowReason_Incremental: + printf("Inc");break; + case eReflowReason_Resize: + printf("Rsz");break; + case eReflowReason_StyleChange: + printf("Sty");break; + case eReflowReason_Dirty: + printf("Drt "); + break; + default:printf("%d", aReflowInput.reason);break; + } + + printSize("AW", aReflowInput.AvailableWidth()); + printSize("AH", aReflowInput.AvailableHeight()); + printSize("CW", aReflowInput.ComputedWidth()); + printSize("CH", aReflowInput.ComputedHeight()); + + printf(" *\n"); + +#endif + + aStatus = NS_FRAME_COMPLETE; + + // create the layout state + nsBoxLayoutState state(aPresContext, aReflowInput.mRenderingContext); + + nsSize computedSize(aReflowInput.ComputedWidth(),aReflowInput.ComputedHeight()); + + nsMargin m; + m = aReflowInput.ComputedPhysicalBorderPadding(); + + //GetXULBorderAndPadding(m); + + // this happens sometimes. So lets handle it gracefully. + if (aReflowInput.ComputedHeight() == 0) { + nsSize minSize = GetXULMinSize(state); + computedSize.height = minSize.height - m.top - m.bottom; + } + + nsSize prefSize(0,0); + + // if we are told to layout intrinic then get our preferred size. + if (computedSize.width == NS_INTRINSICSIZE || computedSize.height == NS_INTRINSICSIZE) { + prefSize = GetXULPrefSize(state); + nsSize minSize = GetXULMinSize(state); + nsSize maxSize = GetXULMaxSize(state); + prefSize = BoundsCheck(minSize, prefSize, maxSize); + } + + // get our desiredSize + if (aReflowInput.ComputedWidth() == NS_INTRINSICSIZE) { + computedSize.width = prefSize.width; + } else { + computedSize.width += m.left + m.right; + } + + if (aReflowInput.ComputedHeight() == NS_INTRINSICSIZE) { + computedSize.height = prefSize.height; + } else { + computedSize.height += m.top + m.bottom; + } + + // handle reflow state min and max sizes + // XXXbz the width handling here seems to be wrong, since + // mComputedMin/MaxWidth is a content-box size, whole + // computedSize.width is a border-box size... + if (computedSize.width > aReflowInput.ComputedMaxWidth()) + computedSize.width = aReflowInput.ComputedMaxWidth(); + + if (computedSize.width < aReflowInput.ComputedMinWidth()) + computedSize.width = aReflowInput.ComputedMinWidth(); + + // Now adjust computedSize.height for our min and max computed + // height. The only problem is that those are content-box sizes, + // while computedSize.height is a border-box size. So subtract off + // m.TopBottom() before adjusting, then readd it. + computedSize.height = std::max(0, computedSize.height - m.TopBottom()); + computedSize.height = NS_CSS_MINMAX(computedSize.height, + aReflowInput.ComputedMinHeight(), + aReflowInput.ComputedMaxHeight()); + computedSize.height += m.TopBottom(); + + nsRect r(mRect.x, mRect.y, computedSize.width, computedSize.height); + + SetXULBounds(state, r); + + // layout our children + XULLayout(state); + + // ok our child could have gotten bigger. So lets get its bounds + aDesiredSize.Width() = mRect.width; + aDesiredSize.Height() = mRect.height; + aDesiredSize.SetBlockStartAscent(GetXULBoxAscent(state)); + + // the overflow rect is set in SetXULBounds() above + aDesiredSize.mOverflowAreas = GetOverflowAreas(); + +#ifdef DO_NOISY_REFLOW + { + printf("%p ** nsLBF(done) W:%d H:%d ", this, aDesiredSize.Width(), aDesiredSize.Height()); + + if (maxElementWidth) { + printf("MW:%d\n", *maxElementWidth); + } else { + printf("MW:?\n"); + } + + } +#endif +} + +#ifdef DEBUG_FRAME_DUMP +nsresult +nsLeafBoxFrame::GetFrameName(nsAString& aResult) const +{ + return MakeFrameName(NS_LITERAL_STRING("LeafBox"), aResult); +} +#endif + +nsIAtom* +nsLeafBoxFrame::GetType() const +{ + return nsGkAtoms::leafBoxFrame; +} + +nsresult +nsLeafBoxFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo) +{ + MarkIntrinsicISizesDirty(); + return nsLeafFrame::CharacterDataChanged(aInfo); +} + +/* virtual */ nsSize +nsLeafBoxFrame::GetXULPrefSize(nsBoxLayoutState& aState) +{ + return nsBox::GetXULPrefSize(aState); +} + +/* virtual */ nsSize +nsLeafBoxFrame::GetXULMinSize(nsBoxLayoutState& aState) +{ + return nsBox::GetXULMinSize(aState); +} + +/* virtual */ nsSize +nsLeafBoxFrame::GetXULMaxSize(nsBoxLayoutState& aState) +{ + return nsBox::GetXULMaxSize(aState); +} + +/* virtual */ nscoord +nsLeafBoxFrame::GetXULFlex() +{ + return nsBox::GetXULFlex(); +} + +/* virtual */ nscoord +nsLeafBoxFrame::GetXULBoxAscent(nsBoxLayoutState& aState) +{ + return nsBox::GetXULBoxAscent(aState); +} + +/* virtual */ void +nsLeafBoxFrame::MarkIntrinsicISizesDirty() +{ + // Don't call base class method, since everything it does is within an + // IsXULBoxWrapped check. +} + +NS_IMETHODIMP +nsLeafBoxFrame::DoXULLayout(nsBoxLayoutState& aState) +{ + return nsBox::DoXULLayout(aState); +} -- cgit v1.2.3