Skip to content

Commit

Permalink
Rendering issue with checkbox in flexbox layout
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=255419
<rdar://problem/108026194>

Reviewed by Antti Koivisto.

Form controls with appearance are supposed to set their minimum (intrinsic) widths so that they don't get overlapped (e.g. by getting sized to 0px)
in over-constrained situations.

* LayoutTests/fast/flexbox/overlapped-form-controls-expected.html: Added.
* LayoutTests/fast/flexbox/overlapped-form-controls.html: Added.
* Source/WebCore/platform/Theme.cpp:
(WebCore::Theme::minimumControlSize const):

Canonical link: https://commits.webkit.org/263052@main
  • Loading branch information
alanbaradlay committed Apr 18, 2023
1 parent 62a3751 commit a6b2a57
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 9 deletions.
10 changes: 10 additions & 0 deletions LayoutTests/fast/flexbox/overlapped-form-controls-expected.html
@@ -0,0 +1,10 @@
<style>
div {
position: absolute;
}
input {
outline: solid 1px black;
}
</style>
<div><input type="checkbox"></div>
<div style="top: 100px;"><input type="radio"></div>
15 changes: 15 additions & 0 deletions LayoutTests/fast/flexbox/overlapped-form-controls.html
@@ -0,0 +1,15 @@
<style>
div {
max-width: 30px;
display: flex;
color: transparent;
font-family: Ahem;
font-size: 10px;
position: absolute;
}
input {
outline: solid 1px black;
}
</style>
<div><input type="checkbox">PASS if form control is not overlapped.</div>
<div style="top: 100px;"><input type="radio">PASS if form control is not overlapped.</div>

This file was deleted.

3 changes: 2 additions & 1 deletion Source/WebCore/platform/Theme.cpp
Expand Up @@ -51,7 +51,8 @@ LengthSize Theme::controlSize(StyleAppearance, const FontCascade&, const LengthS
LengthSize Theme::minimumControlSize(StyleAppearance appearance, const FontCascade& fontCascade, const LengthSize& zoomedSize, const LengthSize& nonShrinkableZoomedSize, float zoom) const
{
auto minSize = minimumControlSize(appearance, fontCascade, zoomedSize, zoom);
if (appearance == StyleAppearance::Radio) {
// Other StyleAppearance types are composed controls with shadow subtree.
if (appearance == StyleAppearance::Radio || appearance == StyleAppearance::Checkbox) {
if (zoomedSize.width.isIntrinsicOrAuto())
minSize.width = nonShrinkableZoomedSize.width;
if (zoomedSize.height.isIntrinsicOrAuto())
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/rendering/RenderThemeIOS.h
Expand Up @@ -204,6 +204,7 @@ class RenderThemeIOS final : public RenderThemeCocoa {
Color controlTintColor(const RenderStyle&, OptionSet<StyleColorOptions>) const;

void adjustStyleForAlternateFormControlDesignTransition(RenderStyle&, const Element*) const;
void adjustMinimumIntrinsicSizeForAppearance(StyleAppearance, RenderStyle&) const;
};

}
Expand Down
11 changes: 11 additions & 0 deletions Source/WebCore/rendering/RenderThemeIOS.mm
Expand Up @@ -342,6 +342,7 @@ static IOSGradientRef gradientWithName(IOSGradientType gradientType)
void RenderThemeIOS::adjustCheckboxStyle(RenderStyle& style, const Element* element) const
{
adjustStyleForAlternateFormControlDesignTransition(style, element);
adjustMinimumIntrinsicSizeForAppearance(StyleAppearance::Checkbox, style);

if (!style.width().isIntrinsicOrAuto() && !style.height().isAuto())
return;
Expand Down Expand Up @@ -488,9 +489,19 @@ static void drawJoinedLines(CGContextRef context, const Vector<CGPoint>& points,
return RenderTheme::isControlStyled(style, userAgentStyle);
}

void RenderThemeIOS::adjustMinimumIntrinsicSizeForAppearance(StyleAppearance appearance, RenderStyle& style) const
{
auto minControlSize = Theme::singleton().minimumControlSize(appearance, style.fontCascade(), { style.minWidth(), style.minHeight() }, { style.width(), style.height() }, style.effectiveZoom());
if (minControlSize.width.value() > style.minWidth().value())
style.setMinWidth(WTFMove(minControlSize.width));
if (minControlSize.height.value() > style.minHeight().value())
style.setMinHeight(WTFMove(minControlSize.height));
}

void RenderThemeIOS::adjustRadioStyle(RenderStyle& style, const Element* element) const
{
adjustStyleForAlternateFormControlDesignTransition(style, element);
adjustMinimumIntrinsicSizeForAppearance(StyleAppearance::Radio, style);

if (!style.width().isIntrinsicOrAuto() && !style.height().isAuto())
return;
Expand Down

0 comments on commit a6b2a57

Please sign in to comment.