diff options
Diffstat (limited to 'layout/forms')
-rw-r--r-- | layout/forms/nsFieldSetFrame.cpp | 71 | ||||
-rw-r--r-- | layout/forms/nsFieldSetFrame.h | 10 | ||||
-rw-r--r-- | layout/forms/nsHTMLButtonControlFrame.cpp | 41 | ||||
-rw-r--r-- | layout/forms/nsHTMLButtonControlFrame.h | 7 | ||||
-rw-r--r-- | layout/forms/nsLegendFrame.h | 5 | ||||
-rw-r--r-- | layout/forms/nsTextControlFrame.cpp | 11 | ||||
-rw-r--r-- | layout/forms/nsTextControlFrame.h | 35 | ||||
-rw-r--r-- | layout/forms/test/test_bug562447.html | 6 | ||||
-rw-r--r-- | layout/forms/test/test_bug564115.html | 4 |
9 files changed, 159 insertions, 31 deletions
diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp index befd41ee2..fc9f0571b 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -5,26 +5,22 @@ #include "nsFieldSetFrame.h" +#include <algorithm> #include "mozilla/gfx/2D.h" +#include "mozilla/Likely.h" +#include "mozilla/Maybe.h" #include "nsCSSAnonBoxes.h" -#include "nsLayoutUtils.h" -#include "nsLegendFrame.h" #include "nsCSSRendering.h" -#include <algorithm> -#include "nsIFrame.h" -#include "nsPresContext.h" -#include "mozilla/RestyleManager.h" -#include "nsGkAtoms.h" -#include "nsStyleConsts.h" #include "nsDisplayList.h" +#include "nsGkAtoms.h" +#include "nsIFrameInlines.h" +#include "nsLayoutUtils.h" +#include "nsLegendFrame.h" #include "nsRenderingContext.h" -#include "nsIScrollableFrame.h" -#include "mozilla/Likely.h" -#include "mozilla/Maybe.h" +#include "nsStyleConsts.h" using namespace mozilla; using namespace mozilla::gfx; -using namespace mozilla::image; using namespace mozilla::layout; nsContainerFrame* @@ -126,7 +122,7 @@ void nsDisplayFieldSetBorderBackground::Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) { - DrawResult result = static_cast<nsFieldSetFrame*>(mFrame)-> + image::DrawResult result = static_cast<nsFieldSetFrame*>(mFrame)-> PaintBorder(aBuilder, *aCtx, ToReferenceFrame(), mVisibleRect); nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result); @@ -210,7 +206,7 @@ nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, contentDisplayItems.MoveTo(aLists); } -DrawResult +image::DrawResult nsFieldSetFrame::PaintBorder( nsDisplayListBuilder* aBuilder, nsRenderingContext& aRenderingContext, @@ -695,9 +691,50 @@ nsFieldSetFrame::AccessibleType() #endif nscoord -nsFieldSetFrame::GetLogicalBaseline(WritingMode aWritingMode) const +nsFieldSetFrame::GetLogicalBaseline(WritingMode aWM) const +{ + switch (StyleDisplay()->mDisplay) { + case mozilla::StyleDisplay::Grid: + case mozilla::StyleDisplay::InlineGrid: + case mozilla::StyleDisplay::Flex: + case mozilla::StyleDisplay::InlineFlex: + return BaselineBOffset(aWM, BaselineSharingGroup::eFirst, + AlignmentContext::eInline); + default: + return BSize(aWM) - BaselineBOffset(aWM, BaselineSharingGroup::eLast, + AlignmentContext::eInline); + } +} + +bool +nsFieldSetFrame::GetVerticalAlignBaseline(WritingMode aWM, + nscoord* aBaseline) const { nsIFrame* inner = GetInner(); - return inner->BStart(aWritingMode, GetParent()->GetSize()) + - inner->GetLogicalBaseline(aWritingMode); + MOZ_ASSERT(!inner->GetWritingMode().IsOrthogonalTo(aWM)); + if (!inner->GetVerticalAlignBaseline(aWM, aBaseline)) { + return false; + } + nscoord innerBStart = inner->BStart(aWM, GetSize()); + *aBaseline += innerBStart; + return true; +} + +bool +nsFieldSetFrame::GetNaturalBaselineBOffset(WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const +{ + nsIFrame* inner = GetInner(); + MOZ_ASSERT(!inner->GetWritingMode().IsOrthogonalTo(aWM)); + if (!inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aBaseline)) { + return false; + } + nscoord innerBStart = inner->BStart(aWM, GetSize()); + if (aBaselineGroup == BaselineSharingGroup::eFirst) { + *aBaseline += innerBStart; + } else { + *aBaseline += BSize(aWM) - (innerBStart + inner->BSize(aWM)); + } + return true; } diff --git a/layout/forms/nsFieldSetFrame.h b/layout/forms/nsFieldSetFrame.h index 54eaf678f..5eb67c320 100644 --- a/layout/forms/nsFieldSetFrame.h +++ b/layout/forms/nsFieldSetFrame.h @@ -7,7 +7,7 @@ #define nsFieldSetFrame_h___ #include "mozilla/Attributes.h" -#include "imgIContainer.h" +#include "DrawResult.h" #include "nsContainerFrame.h" class nsFieldSetFrame final : public nsContainerFrame @@ -33,7 +33,6 @@ public: const mozilla::LogicalSize& aBorder, const mozilla::LogicalSize& aPadding, ComputeSizeFlags aFlags) override; - virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override; /** * The area to paint box-shadows around. It's the border rect except @@ -46,6 +45,13 @@ public: const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; + nscoord GetLogicalBaseline(mozilla::WritingMode aWM) const override; + bool GetVerticalAlignBaseline(mozilla::WritingMode aWM, + nscoord* aBaseline) const override; + bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const override; + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; diff --git a/layout/forms/nsHTMLButtonControlFrame.cpp b/layout/forms/nsHTMLButtonControlFrame.cpp index ef9459ef2..2e4fa9f67 100644 --- a/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/layout/forms/nsHTMLButtonControlFrame.cpp @@ -418,6 +418,47 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext, aButtonDesiredSize.SetOverflowAreasToDesiredBounds(); } +bool +nsHTMLButtonControlFrame::GetVerticalAlignBaseline(mozilla::WritingMode aWM, + nscoord* aBaseline) const +{ + nsIFrame* inner = mFrames.FirstChild(); + if (MOZ_UNLIKELY(inner->GetWritingMode().IsOrthogonalTo(aWM))) { + return false; + } + if (!inner->GetVerticalAlignBaseline(aWM, aBaseline)) { + // <input type=color> has an empty block frame as inner frame + *aBaseline = inner-> + SynthesizeBaselineBOffsetFromBorderBox(aWM, BaselineSharingGroup::eFirst); + } + nscoord innerBStart = inner->BStart(aWM, GetSize()); + *aBaseline += innerBStart; + return true; +} + +bool +nsHTMLButtonControlFrame::GetNaturalBaselineBOffset(mozilla::WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const +{ + nsIFrame* inner = mFrames.FirstChild(); + if (MOZ_UNLIKELY(inner->GetWritingMode().IsOrthogonalTo(aWM))) { + return false; + } + if (!inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aBaseline)) { + // <input type=color> has an empty block frame as inner frame + *aBaseline = inner-> + SynthesizeBaselineBOffsetFromBorderBox(aWM, aBaselineGroup); + } + nscoord innerBStart = inner->BStart(aWM, GetSize()); + if (aBaselineGroup == BaselineSharingGroup::eFirst) { + *aBaseline += innerBStart; + } else { + *aBaseline += BSize(aWM) - (innerBStart + inner->BSize(aWM)); + } + return true; +} + nsresult nsHTMLButtonControlFrame::SetFormProperty(nsIAtom* aName, const nsAString& aValue) { if (nsGkAtoms::value == aName) { diff --git a/layout/forms/nsHTMLButtonControlFrame.h b/layout/forms/nsHTMLButtonControlFrame.h index 96ad0f366..432afa12c 100644 --- a/layout/forms/nsHTMLButtonControlFrame.h +++ b/layout/forms/nsHTMLButtonControlFrame.h @@ -39,6 +39,13 @@ public: const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; + bool GetVerticalAlignBaseline(mozilla::WritingMode aWM, + nscoord* aBaseline) const override; + + bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const override; + virtual nsresult HandleEvent(nsPresContext* aPresContext, mozilla::WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) override; diff --git a/layout/forms/nsLegendFrame.h b/layout/forms/nsLegendFrame.h index 5f5e1e03e..a9e11cbbe 100644 --- a/layout/forms/nsLegendFrame.h +++ b/layout/forms/nsLegendFrame.h @@ -9,7 +9,8 @@ #include "mozilla/Attributes.h" #include "nsBlockFrame.h" -class nsLegendFrame : public nsBlockFrame { +class nsLegendFrame final : public nsBlockFrame +{ public: NS_DECL_QUERYFRAME_TARGET(nsLegendFrame) NS_DECL_QUERYFRAME @@ -30,7 +31,7 @@ public: virtual nsresult GetFrameName(nsAString& aResult) const override; #endif - int32_t GetLogicalAlign(WritingMode aCBWM); + int32_t GetLogicalAlign(mozilla::WritingMode aCBWM); }; diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index f85bc2a80..a7f7d40a8 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -106,6 +106,7 @@ private: nsTextControlFrame::nsTextControlFrame(nsStyleContext* aContext) : nsContainerFrame(aContext) + , mFirstBaseline(NS_INTRINSIC_WIDTH_UNKNOWN) , mEditorHasBeenInitialized(false) , mIsProcessing(false) #ifdef DEBUG @@ -538,20 +539,20 @@ nsTextControlFrame::Reflow(nsPresContext* aPresContext, aReflowInput.ComputedLogicalBorderPadding().BStartEnd(wm)); aDesiredSize.SetSize(wm, finalSize); - // computation of the ascent wrt the input height + // Calculate the baseline and store it in mFirstBaseline. nscoord lineHeight = aReflowInput.ComputedBSize(); float inflation = nsLayoutUtils::FontSizeInflationFor(this); if (!IsSingleLineTextControl()) { lineHeight = ReflowInput::CalcLineHeight(GetContent(), StyleContext(), - NS_AUTOHEIGHT, inflation); + NS_AUTOHEIGHT, inflation); } RefPtr<nsFontMetrics> fontMet = nsLayoutUtils::GetFontMetricsForFrame(this, inflation); - // now adjust for our borders and padding - aDesiredSize.SetBlockStartAscent( + mFirstBaseline = nsLayoutUtils::GetCenteredFontBaseline(fontMet, lineHeight, wm.IsLineInverted()) + - aReflowInput.ComputedLogicalBorderPadding().BStart(wm)); + aReflowInput.ComputedLogicalBorderPadding().BStart(wm); + aDesiredSize.SetBlockStartAscent(mFirstBaseline); // overflow handling aDesiredSize.SetOverflowAreasToDesiredBounds(); diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h index a76cba514..9d4d0b77c 100644 --- a/layout/forms/nsTextControlFrame.h +++ b/layout/forms/nsTextControlFrame.h @@ -62,6 +62,29 @@ public: const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; + bool GetVerticalAlignBaseline(mozilla::WritingMode aWM, + nscoord* aBaseline) const override + { + return GetNaturalBaselineBOffset(aWM, BaselineSharingGroup::eFirst, aBaseline); + } + + bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const override + { + if (!IsSingleLineTextControl()) { + return false; + } + NS_ASSERTION(mFirstBaseline != NS_INTRINSIC_WIDTH_UNKNOWN, + "please call Reflow before asking for the baseline"); + if (aBaselineGroup == BaselineSharingGroup::eFirst) { + *aBaseline = mFirstBaseline; + } else { + *aBaseline = BSize(aWM) - mFirstBaseline; + } + return true; + } + virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override; virtual bool IsXULCollapsed() override; @@ -87,6 +110,14 @@ public: ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock)); } +#ifdef DEBUG + void MarkIntrinsicISizesDirty() override + { + // Need another Reflow to have a correct baseline value again. + mFirstBaseline = NS_INTRINSIC_WIDTH_UNKNOWN; + } +#endif + // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override; virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, @@ -300,6 +331,10 @@ private: } private: + // Our first baseline, or NS_INTRINSIC_WIDTH_UNKNOWN if we have a pending + // Reflow. + nscoord mFirstBaseline; + // these packed bools could instead use the high order bits on mState, saving 4 bytes bool mEditorHasBeenInitialized; bool mIsProcessing; diff --git a/layout/forms/test/test_bug562447.html b/layout/forms/test/test_bug562447.html index 53f84428e..99f691871 100644 --- a/layout/forms/test/test_bug562447.html +++ b/layout/forms/test/test_bug562447.html @@ -23,7 +23,7 @@ addLoadEvent(function() { setTimeout(function() { // Make sure that we're scrolled by 5000px - is(window.pageYOffset, 5000, "Make sure we're scrolled correctly"); + is(Math.round(window.pageYOffset), 5000, "Make sure we're scrolled correctly"); // Scroll back up, and mess with the input box along the way var input = document.getElementById("WhyDoYouFocusMe"); @@ -38,14 +38,14 @@ addLoadEvent(function() { window.scrollTo(0, 5000); setTimeout(function() { - is(window.pageYOffset, 5000, "Sanity check"); + is(Math.round(window.pageYOffset), 5000, "Sanity check"); window.scrollTo(0, 0); input.focus(); input.blur(); setTimeout(function() { - isnot(window.pageYOffset, 0, "This time we shouldn't be scrolled up"); + isnot(Math.round(window.pageYOffset), 0, "This time we shouldn't be scrolled up"); SimpleTest.finish(); }, 0); diff --git a/layout/forms/test/test_bug564115.html b/layout/forms/test/test_bug564115.html index 5723b55d5..ffd4222ca 100644 --- a/layout/forms/test/test_bug564115.html +++ b/layout/forms/test/test_bug564115.html @@ -30,12 +30,12 @@ addLoadEvent(function() { win.scrollTo(0, 5000); setTimeout(function() { - is(win.pageYOffset, 5000, "Page should be scrolled correctly"); + is(Math.round(win.pageYOffset), 5000, "Page should be scrolled correctly"); // Refocus the window SimpleTest.waitForFocus(function() { SimpleTest.waitForFocus(function() { - is(win.pageYOffset, 5000, + is(Math.round(win.pageYOffset), 5000, "The page's scroll offset should not have been changed"); win.close(); |