diff options
author | janekptacijarabaci <janekptacijarabaci@seznam.cz> | 2017-08-17 21:08:44 +0200 |
---|---|---|
committer | wolfbeast <mcwerewolf@gmail.com> | 2018-03-12 09:50:12 +0100 |
commit | 092c61f6e68971a62822532e12dc45ba54c9a713 (patch) | |
tree | b3e1aa03886aded4e908c834caf69bba13b507e7 /layout/forms | |
parent | 76e1c016a32cb8cee6f5a0a0012fe512570da1eb (diff) | |
download | UXP-092c61f6e68971a62822532e12dc45ba54c9a713.tar UXP-092c61f6e68971a62822532e12dc45ba54c9a713.tar.gz UXP-092c61f6e68971a62822532e12dc45ba54c9a713.tar.lz UXP-092c61f6e68971a62822532e12dc45ba54c9a713.tar.xz UXP-092c61f6e68971a62822532e12dc45ba54c9a713.zip |
CSS: inline-block with a display:block <input> child element has a wrong baseline (HTML forms)
Diffstat (limited to 'layout/forms')
-rw-r--r-- | layout/forms/nsFieldSetFrame.cpp | 71 | ||||
-rw-r--r-- | layout/forms/nsFieldSetFrame.h | 9 | ||||
-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 |
7 files changed, 154 insertions, 25 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..39d862278 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 @@ -46,6 +46,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; |