summaryrefslogtreecommitdiffstats
path: root/layout/forms
diff options
context:
space:
mode:
authorjanekptacijarabaci <janekptacijarabaci@seznam.cz>2017-08-17 21:08:44 +0200
committerwolfbeast <mcwerewolf@gmail.com>2018-03-12 09:50:12 +0100
commit092c61f6e68971a62822532e12dc45ba54c9a713 (patch)
treeb3e1aa03886aded4e908c834caf69bba13b507e7 /layout/forms
parent76e1c016a32cb8cee6f5a0a0012fe512570da1eb (diff)
downloadUXP-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.cpp71
-rw-r--r--layout/forms/nsFieldSetFrame.h9
-rw-r--r--layout/forms/nsHTMLButtonControlFrame.cpp41
-rw-r--r--layout/forms/nsHTMLButtonControlFrame.h7
-rw-r--r--layout/forms/nsLegendFrame.h5
-rw-r--r--layout/forms/nsTextControlFrame.cpp11
-rw-r--r--layout/forms/nsTextControlFrame.h35
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;