Bug 1698043 - Simplify <input type=number/search> layout to fix this bug and make ::-moz-complex-control-wrapper unnecessary. r=dholbert
This should be a simpler setup. We keep every element being a direct anon child of the text control, and special case the reflow of the spinners / clear button, to subtract that size from the other elements. This fixes the bug by ensuring that the editor and placeholder are sized and positioned in exactly the same way. Differential Revision: https://phabricator.services.mozilla.com/D108305
This commit is contained in:
@@ -149,13 +149,7 @@ void nsTextControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
|
||||
|
||||
// If we're a subclass like nsNumberControlFrame, then it owns the root of the
|
||||
// anonymous subtree where mRootNode is.
|
||||
if (mClass == kClassID) {
|
||||
aPostDestroyData.AddAnonymousContent(mRootNode.forget());
|
||||
} else {
|
||||
MOZ_ASSERT(!mRootNode || !mRootNode->IsRootOfNativeAnonymousSubtree());
|
||||
mRootNode = nullptr;
|
||||
}
|
||||
|
||||
aPostDestroyData.AddAnonymousContent(mRootNode.forget());
|
||||
aPostDestroyData.AddAnonymousContent(mPlaceholderDiv.forget());
|
||||
aPostDestroyData.AddAnonymousContent(mPreviewDiv.forget());
|
||||
|
||||
@@ -636,9 +630,10 @@ void nsTextControlFrame::Reflow(nsPresContext* aPresContext,
|
||||
aDesiredSize.SetOverflowAreasToDesiredBounds();
|
||||
// perform reflow on all kids
|
||||
nsIFrame* kid = mFrames.FirstChild();
|
||||
nscoord buttonBoxISize = 0;
|
||||
while (kid) {
|
||||
ReflowTextControlChild(kid, aPresContext, aReflowInput, aStatus,
|
||||
aDesiredSize);
|
||||
aDesiredSize, buttonBoxISize);
|
||||
kid = kid->GetNextSibling();
|
||||
}
|
||||
|
||||
@@ -652,37 +647,74 @@ void nsTextControlFrame::Reflow(nsPresContext* aPresContext,
|
||||
void nsTextControlFrame::ReflowTextControlChild(
|
||||
nsIFrame* aKid, nsPresContext* aPresContext,
|
||||
const ReflowInput& aReflowInput, nsReflowStatus& aStatus,
|
||||
ReflowOutput& aParentDesiredSize) {
|
||||
ReflowOutput& aParentDesiredSize, nscoord& aButtonBoxISize) {
|
||||
const WritingMode outerWM = aReflowInput.GetWritingMode();
|
||||
// compute available size and frame offsets for child
|
||||
WritingMode wm = aKid->GetWritingMode();
|
||||
const WritingMode wm = aKid->GetWritingMode();
|
||||
LogicalSize availSize = aReflowInput.ComputedSizeWithPadding(wm);
|
||||
availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
|
||||
|
||||
const bool isButtonBox =
|
||||
aKid->Style()->GetPseudoType() == PseudoStyleType::mozNumberSpinBox ||
|
||||
aKid->Style()->GetPseudoType() == PseudoStyleType::mozSearchClearButton;
|
||||
|
||||
ReflowInput kidReflowInput(aPresContext, aReflowInput, aKid, availSize,
|
||||
Nothing(), ReflowInput::InitFlag::CallerWillInit);
|
||||
|
||||
// Override padding with our computed padding in case we got it from theming
|
||||
// or percentage.
|
||||
kidReflowInput.Init(aPresContext, Nothing(), Nothing(),
|
||||
Some(aReflowInput.ComputedLogicalPadding(wm)));
|
||||
// or percentage, if we're not the button box.
|
||||
auto overridePadding =
|
||||
isButtonBox ? Nothing() : Some(aReflowInput.ComputedLogicalPadding(wm));
|
||||
kidReflowInput.Init(aPresContext, Nothing(), Nothing(), overridePadding);
|
||||
|
||||
// Set computed width and computed height for the child
|
||||
kidReflowInput.SetComputedWidth(aReflowInput.ComputedWidth());
|
||||
kidReflowInput.SetComputedHeight(aReflowInput.ComputedHeight());
|
||||
LogicalPoint position(wm);
|
||||
const auto& bp = aReflowInput.ComputedLogicalBorderPadding(outerWM);
|
||||
|
||||
// Offset the frame by the size of the parent's border
|
||||
nscoord xOffset = aReflowInput.ComputedPhysicalBorderPadding().left -
|
||||
aReflowInput.ComputedPhysicalPadding().left;
|
||||
nscoord yOffset = aReflowInput.ComputedPhysicalBorderPadding().top -
|
||||
aReflowInput.ComputedPhysicalPadding().top;
|
||||
if (!isButtonBox) {
|
||||
MOZ_ASSERT(wm == outerWM,
|
||||
"Shouldn't have to care about orthogonal "
|
||||
"writing-modes and such inside the control, "
|
||||
"except for the number spin-box which forces "
|
||||
"horizontal-tb");
|
||||
|
||||
// Offset the frame by the size of the parent's border
|
||||
const auto& padding = aReflowInput.ComputedLogicalPadding(wm);
|
||||
position.B(wm) = bp.BStart(wm) - padding.BStart(wm);
|
||||
position.I(wm) = bp.IStart(wm) - padding.IStart(wm);
|
||||
|
||||
// Set computed width and computed height for the child (the button box is
|
||||
// the only exception, which has an auto size).
|
||||
kidReflowInput.SetComputedISize(
|
||||
std::max(0, aReflowInput.ComputedISize() - aButtonBoxISize));
|
||||
kidReflowInput.SetComputedBSize(aReflowInput.ComputedBSize());
|
||||
}
|
||||
|
||||
// reflow the child
|
||||
ReflowOutput desiredSize(aReflowInput);
|
||||
ReflowChild(aKid, aPresContext, desiredSize, kidReflowInput, xOffset, yOffset,
|
||||
ReflowChildFlags::Default, aStatus);
|
||||
const nsSize containerSize =
|
||||
aReflowInput.ComputedSizeWithBorderPadding(outerWM).GetPhysicalSize(
|
||||
outerWM);
|
||||
ReflowChild(aKid, aPresContext, desiredSize, kidReflowInput, wm, position,
|
||||
containerSize, ReflowChildFlags::Default, aStatus);
|
||||
|
||||
if (isButtonBox) {
|
||||
auto size = desiredSize.Size(outerWM);
|
||||
// Center button in the block axis of our content box. We do this
|
||||
// computation in terms of outerWM for simplicity.
|
||||
position = LogicalPoint(outerWM);
|
||||
position.B(outerWM) =
|
||||
bp.BStart(outerWM) +
|
||||
(aReflowInput.ComputedBSize() - size.BSize(outerWM)) / 2;
|
||||
// Align to the inline-end of the content box.
|
||||
position.I(outerWM) =
|
||||
bp.IStart(outerWM) + aReflowInput.ComputedISize() - size.ISize(outerWM);
|
||||
position = position.ConvertTo(wm, outerWM, containerSize);
|
||||
aButtonBoxISize = size.ISize(outerWM);
|
||||
}
|
||||
|
||||
// place the child
|
||||
FinishReflowChild(aKid, aPresContext, desiredSize, &kidReflowInput, xOffset,
|
||||
yOffset, ReflowChildFlags::Default);
|
||||
FinishReflowChild(aKid, aPresContext, desiredSize, &kidReflowInput, wm,
|
||||
position, containerSize, ReflowChildFlags::Default);
|
||||
|
||||
// consider the overflow
|
||||
aParentDesiredSize.mOverflowAreas.UnionWith(desiredSize.mOverflowAreas);
|
||||
|
||||
Reference in New Issue
Block a user