blob: 90e3bcb8088080e70173d65296fcf8dadd020304 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/html/forms/menu_list_inner_element.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
#include "third_party/blink/renderer/core/layout/layout_theme.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
namespace blink {
MenuListInnerElement::MenuListInnerElement(Document& document)
: HTMLDivElement(document) {
SetHasCustomStyleCallbacks();
}
scoped_refptr<ComputedStyle> MenuListInnerElement::CustomStyleForLayoutObject(
const StyleRecalcContext& style_recalc_context) {
const ComputedStyle& parent_style = OwnerShadowHost()->ComputedStyleRef();
scoped_refptr<ComputedStyle> style =
ComputedStyle::CreateAnonymousStyleWithDisplay(parent_style,
EDisplay::kBlock);
style->SetFlexGrow(1);
style->SetFlexShrink(1);
// min-width: 0; is needed for correct shrinking.
style->SetMinWidth(Length::Fixed(0));
style->SetHasLineIfEmpty(true);
style->SetOverflowX(EOverflow::kHidden);
style->SetOverflowY(EOverflow::kHidden);
style->SetShouldIgnoreOverflowPropertyForInlineBlockBaseline();
style->SetTextOverflow(parent_style.TextOverflow());
style->SetUserModify(EUserModify::kReadOnly);
if (style->LineHeight() == ComputedStyleInitialValues::InitialLineHeight()) {
// line-height should be consistent with MenuListIntrinsicBlockSize()
// in layout_box.cc.
const SimpleFontData* font_data = style->GetFont().PrimaryFont();
if (font_data)
style->SetLineHeight(Length::Fixed(font_data->GetFontMetrics().Height()));
else
style->SetLineHeight(Length::Fixed(style->FontSize()));
}
// Use margin:auto instead of align-items:center to get safe centering, i.e.
// when the content overflows, treat it the same as align-items: flex-start.
// But we only do that for the cases where html.css would otherwise use
// center.
if (parent_style.AlignItemsPosition() == ItemPosition::kCenter) {
style->SetMarginTop(Length());
style->SetMarginBottom(Length());
style->SetAlignSelfPosition(ItemPosition::kFlexStart);
}
// We set margin-left/right instead of padding-left/right to clip text by
// 'overflow: hidden'.
LayoutTheme& theme = LayoutTheme::GetTheme();
Length margin_start =
Length::Fixed(theme.PopupInternalPaddingStart(parent_style));
Length margin_end = Length::Fixed(
theme.PopupInternalPaddingEnd(GetDocument().GetFrame(), parent_style));
if (parent_style.IsLeftToRightDirection()) {
style->SetTextAlign(ETextAlign::kLeft);
style->SetMarginLeft(margin_start);
style->SetMarginRight(margin_end);
} else {
style->SetTextAlign(ETextAlign::kRight);
style->SetMarginLeft(margin_end);
style->SetMarginRight(margin_start);
}
style->SetPaddingTop(
Length::Fixed(theme.PopupInternalPaddingTop(parent_style)));
style->SetPaddingBottom(
Length::Fixed(theme.PopupInternalPaddingBottom(parent_style)));
if (const ComputedStyle* option_style =
To<HTMLSelectElement>(OwnerShadowHost())->OptionStyle()) {
style->SetDirection(option_style->Direction());
style->SetUnicodeBidi(option_style->GetUnicodeBidi());
}
return style;
}
} // namespace blink