Commit d3904acb authored by Scott Violet's avatar Scott Violet Committed by Commit Bot

blink: adds style logic for overflow: clip

If clip is set along one axis, the other axis must be either visible
or clip. If not, clip is forced to hidden.

This also removes a DCHECK in ComputedStyle::IsOverflowVisible().
I'm going to rename that function shortly
(https://chromium-review.googlesource.com/c/chromium/src/+/2402303)

BUG=1087667
TEST=StyleAdjusterTest

Change-Id: Id00c6cd3269a81a391d541f994b9326a493c7bb8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2402295Reviewed-by: default avatarXiaocheng Hu <xiaochengh@chromium.org>
Commit-Queue: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805948}
parent 70cfb787
......@@ -70,6 +70,10 @@ namespace blink {
namespace {
bool IsOverflowClipOrVisible(EOverflow overflow) {
return overflow == EOverflow::kClip || overflow == EOverflow::kVisible;
}
TouchAction AdjustTouchActionForElement(TouchAction touch_action,
const ComputedStyle& style,
Element* element) {
......@@ -411,17 +415,25 @@ void StyleAdjuster::AdjustOverflow(ComputedStyle& style) {
// If we are left with conflicting overflow values for the x and y axes on a
// table then resolve both to OverflowVisible. This is interoperable
// behaviour but is not specced anywhere.
// TODO(https://crbug.com/966283): figure out how 'clip' should be handled.
if (style.OverflowX() == EOverflow::kVisible)
style.SetOverflowY(EOverflow::kVisible);
else if (style.OverflowY() == EOverflow::kVisible)
style.SetOverflowX(EOverflow::kVisible);
} else if (style.OverflowX() == EOverflow::kVisible &&
style.OverflowY() != EOverflow::kVisible) {
// If either overflow value is not visible, change to auto.
style.SetOverflowX(EOverflow::kAuto);
} else if (style.OverflowY() == EOverflow::kVisible &&
style.OverflowX() != EOverflow::kVisible) {
style.SetOverflowY(EOverflow::kAuto);
} else if (!IsOverflowClipOrVisible(style.OverflowY())) {
// Values of 'clip' and 'visible' can only be used with 'clip' and
// 'visible.' If they aren't, 'clip' and 'visible' is reset.
if (style.OverflowX() == EOverflow::kVisible)
style.SetOverflowX(EOverflow::kAuto);
else if (style.OverflowX() == EOverflow::kClip)
style.SetOverflowX(EOverflow::kHidden);
} else if (!IsOverflowClipOrVisible(style.OverflowX())) {
// Values of 'clip' and 'visible' can only be used with 'clip' and
// 'visible.' If they aren't, 'clip' and 'visible' is reset.
if (style.OverflowY() == EOverflow::kVisible)
style.SetOverflowY(EOverflow::kAuto);
else if (style.OverflowY() == EOverflow::kClip)
style.SetOverflowY(EOverflow::kHidden);
}
}
......
......@@ -106,4 +106,56 @@ TEST_F(StyleAdjusterTest, TouchActionRestrictedByLowerAncestor) {
EXPECT_EQ(TouchAction::kPanX,
target->GetComputedStyle()->GetEffectiveTouchAction());
}
TEST_F(StyleAdjusterTest, AdjustOverflow) {
ScopedOverflowClipForTest overflow_clip_feature_enabler(true);
GetDocument().SetBaseURLOverride(KURL("http://test.com"));
SetBodyInnerHTML(R"HTML(
<div id='clipauto' style='overflow-x: clip; overflow-y: auto;'>
<div id='autoclip' style='overflow-x: auto; overflow-y: clip;'>
<div id='clipclip' style='overflow-x: clip; overflow-y: clip;'>
<div id='visclip' style='overflow-x: visible; overflow-y: clip;'>
<div id='clipvis' style='overflow-x: clip; overflow-y: visible;'>
<div id='hiddenvis' style='overflow-x: hidden; overflow-y: visible;'>
<div id='vishidden' style='overflow-x: visible; overflow-y: hidden;'>
</div>
)HTML");
UpdateAllLifecyclePhasesForTest();
Element* target = GetDocument().getElementById("clipauto");
ASSERT_TRUE(target);
EXPECT_EQ(EOverflow::kHidden, target->GetComputedStyle()->OverflowX());
EXPECT_EQ(EOverflow::kAuto, target->GetComputedStyle()->OverflowY());
target = GetDocument().getElementById("autoclip");
ASSERT_TRUE(target);
EXPECT_EQ(EOverflow::kAuto, target->GetComputedStyle()->OverflowX());
EXPECT_EQ(EOverflow::kHidden, target->GetComputedStyle()->OverflowY());
target = GetDocument().getElementById("clipclip");
ASSERT_TRUE(target);
EXPECT_EQ(EOverflow::kClip, target->GetComputedStyle()->OverflowX());
EXPECT_EQ(EOverflow::kClip, target->GetComputedStyle()->OverflowY());
target = GetDocument().getElementById("visclip");
ASSERT_TRUE(target);
EXPECT_EQ(EOverflow::kVisible, target->GetComputedStyle()->OverflowX());
EXPECT_EQ(EOverflow::kClip, target->GetComputedStyle()->OverflowY());
target = GetDocument().getElementById("clipvis");
ASSERT_TRUE(target);
EXPECT_EQ(EOverflow::kClip, target->GetComputedStyle()->OverflowX());
EXPECT_EQ(EOverflow::kVisible, target->GetComputedStyle()->OverflowY());
target = GetDocument().getElementById("vishidden");
ASSERT_TRUE(target);
EXPECT_EQ(EOverflow::kAuto, target->GetComputedStyle()->OverflowX());
EXPECT_EQ(EOverflow::kHidden, target->GetComputedStyle()->OverflowY());
target = GetDocument().getElementById("hiddenvis");
ASSERT_TRUE(target);
EXPECT_EQ(EOverflow::kHidden, target->GetComputedStyle()->OverflowX());
EXPECT_EQ(EOverflow::kAuto, target->GetComputedStyle()->OverflowY());
}
} // namespace blink
......@@ -2151,11 +2151,12 @@ class ComputedStyle : public ComputedStyleBase,
return IsHorizontalWritingMode() ? OverflowY() : OverflowX();
}
// It's sufficient to just check one direction, since it's illegal to have
// visible on only one overflow value.
// Returns true if 'overflow' is 'visible' along both axes. When 'clip' is
// used the other axis may be 'visible'. In other words, if one axis is
// 'visible' the other axis is not necessarily 'visible.'
bool IsOverflowVisible() const {
DCHECK(OverflowX() != EOverflow::kVisible || OverflowX() == OverflowY());
return OverflowX() == EOverflow::kVisible;
return OverflowX() == EOverflow::kVisible &&
OverflowY() == EOverflow::kVisible;
}
bool IsDisplayTableRowOrColumnType() const {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment