summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/layout/layout_box.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/layout/layout_box.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box.cc680
1 files changed, 426 insertions, 254 deletions
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_box.cc b/chromium/third_party/blink/renderer/core/layout/layout_box.cc
index e9e3cfdf053..d10c1623fc7 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_box.cc
@@ -30,9 +30,11 @@
#include <algorithm>
#include "cc/input/scroll_snap_data.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h"
#include "third_party/blink/public/platform/web_rect.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
+#include "third_party/blink/public/strings/grit/blink_strings.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -40,10 +42,15 @@
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
+#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
+#include "third_party/blink/renderer/core/html/forms/html_opt_group_element.h"
+#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
+#include "third_party/blink/renderer/core/html/html_div_element.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/html_frame_element_base.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
+#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_box.h"
#include "third_party/blink/renderer/core/layout/box_layout_extra_input.h"
@@ -52,6 +59,7 @@
#include "third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_fieldset.h"
+#include "third_party/blink/renderer/core/layout/layout_file_upload_control.h"
#include "third_party/blink/renderer/core/layout/layout_flexible_box.h"
#include "third_party/blink/renderer/core/layout/layout_grid.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
@@ -91,6 +99,7 @@
#include "third_party/blink/renderer/platform/geometry/float_rounded_rect.h"
#include "third_party/blink/renderer/platform/geometry/length_functions.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/text/platform_locale.h"
namespace blink {
@@ -107,13 +116,117 @@ struct SameSizeAsLayoutBox : public LayoutBoxModelObject {
LayoutSize previous_size;
LayoutUnit intrinsic_content_logical_height;
LayoutRectOutsets margin_box_outsets;
- LayoutUnit preferred_logical_width[2];
- void* pointers[5];
+ MinMaxSizes intrinsic_logical_widths;
+ LayoutUnit intrinsic_logical_widths_percentage_resolution_block_size;
+ void* pointers[4];
+ Persistent<void*> rare_data;
+ Vector<scoped_refptr<const NGLayoutResult>, 1> layout_results;
};
static_assert(sizeof(LayoutBox) == sizeof(SameSizeAsLayoutBox),
"LayoutBox should stay small");
+namespace {
+
+LayoutUnit FileUploadControlIntrinsicInlineSize(const HTMLInputElement& input,
+ const LayoutBox& box) {
+ // Figure out how big the filename space needs to be for a given number of
+ // characters (using "0" as the nominal character).
+ constexpr int kDefaultWidthNumChars = 34;
+ constexpr UChar kCharacter = '0';
+ const String character_as_string = String(&kCharacter, 1);
+ const Font& font = box.StyleRef().GetFont();
+ const float min_default_label_width =
+ kDefaultWidthNumChars *
+ font.Width(ConstructTextRun(font, character_as_string, box.StyleRef(),
+ TextRun::kAllowTrailingExpansion));
+
+ const String label =
+ input.GetLocale().QueryString(IDS_FORM_FILE_NO_FILE_LABEL);
+ float default_label_width = font.Width(ConstructTextRun(
+ font, label, box.StyleRef(), TextRun::kAllowTrailingExpansion));
+ if (HTMLInputElement* button = input.UploadButton()) {
+ if (LayoutObject* button_layout_object = button->GetLayoutObject()) {
+ default_label_width +=
+ button_layout_object->PreferredLogicalWidths().max_size +
+ LayoutFileUploadControl::kAfterButtonSpacing;
+ }
+ }
+ return LayoutUnit(
+ ceilf(std::max(min_default_label_width, default_label_width)));
+}
+
+LayoutUnit ListBoxDefaultItemHeight(const LayoutBox& box) {
+ constexpr int kDefaultPaddingBottom = 1;
+
+ const SimpleFontData* font_data = box.StyleRef().GetFont().PrimaryFont();
+ if (!font_data)
+ return LayoutUnit();
+ return LayoutUnit(font_data->GetFontMetrics().Height() +
+ kDefaultPaddingBottom);
+}
+
+// TODO(crbug.com/1040826): This function is written in LayoutObject API
+// so that this works in both of the legacy layout and LayoutNG. We
+// should have LayoutNG-specific code.
+LayoutUnit ListBoxItemHeight(const HTMLSelectElement& select,
+ const LayoutBox& box) {
+ const auto& items = select.GetListItems();
+ if (items.IsEmpty() || box.ShouldApplySizeContainment())
+ return ListBoxDefaultItemHeight(box);
+
+ LayoutUnit max_height;
+ for (Element* element : items) {
+ if (auto* optgroup = DynamicTo<HTMLOptGroupElement>(element))
+ element = &optgroup->OptGroupLabelElement();
+ LayoutUnit item_height;
+ if (auto* layout_box = element->GetLayoutBox())
+ item_height = layout_box->Size().Height();
+ else
+ item_height = ListBoxDefaultItemHeight(box);
+ max_height = std::max(max_height, item_height);
+ }
+ return max_height;
+}
+
+LayoutUnit MenuListIntrinsicInlineSize(const HTMLSelectElement& select,
+ const LayoutBox& box) {
+ const ComputedStyle& style = box.StyleRef();
+ float max_option_width = 0;
+ if (!box.ShouldApplySizeContainment()) {
+ for (auto* const option : select.GetOptionList()) {
+ String text = option->TextIndentedToRespectGroupLabel();
+ const ComputedStyle* item_style =
+ option->GetComputedStyle() ? option->GetComputedStyle() : &style;
+ item_style->ApplyTextTransform(&text);
+ // We apply SELECT's style, not OPTION's style because max_option_width is
+ // used to determine intrinsic width of the menulist box.
+ TextRun text_run = ConstructTextRun(style.GetFont(), text, style);
+ max_option_width =
+ std::max(max_option_width, style.GetFont().Width(text_run));
+ }
+ }
+
+ LayoutTheme& theme = LayoutTheme::GetTheme();
+ int paddings = theme.PopupInternalPaddingStart(style) +
+ theme.PopupInternalPaddingEnd(box.GetFrame(), style);
+ return std::max(static_cast<int>(ceilf(max_option_width)),
+ LayoutTheme::GetTheme().MinimumMenuListSize(style)) +
+ LayoutUnit(paddings);
+}
+
+LayoutUnit MenuListIntrinsicBlockSize(const HTMLSelectElement& select,
+ const LayoutBox& box) {
+ if (!box.StyleRef().HasEffectiveAppearance())
+ return kIndefiniteSize;
+ const SimpleFontData* font_data = box.StyleRef().GetFont().PrimaryFont();
+ DCHECK(font_data);
+ return (font_data ? font_data->GetFontMetrics().Height() : 0) +
+ select.InnerElement().GetLayoutBox()->BorderAndPaddingLogicalHeight();
+}
+
+} // anonymous namespace
+
BoxLayoutExtraInput::BoxLayoutExtraInput(LayoutBox& box) : box(box) {
box.SetBoxLayoutExtraInput(this);
}
@@ -135,11 +248,15 @@ LayoutBoxRareData::LayoutBoxRareData()
snap_container_(nullptr),
snap_areas_(nullptr) {}
+void LayoutBoxRareData::Trace(Visitor* visitor) {
+ visitor->Trace(layout_child_);
+}
+
LayoutBox::LayoutBox(ContainerNode* node)
: LayoutBoxModelObject(node),
intrinsic_content_logical_height_(-1),
- min_preferred_logical_width_(-1),
- max_preferred_logical_width_(-1),
+ intrinsic_logical_widths_percentage_resolution_block_size_(
+ LayoutUnit::Min()),
inline_box_wrapper_(nullptr) {
SetIsBox();
if (blink::IsA<HTMLLegendElement>(node))
@@ -181,6 +298,8 @@ void LayoutBox::WillBeDestroyed() {
if (!DocumentBeingDestroyed()) {
if (NGPaintFragment* first_inline_fragment = FirstInlineFragment())
first_inline_fragment->LayoutObjectWillBeDestroyed();
+ for (auto result : layout_results_)
+ result->PhysicalFragment().LayoutObjectWillBeDestroyed();
}
SetSnapContainer(nullptr);
@@ -242,8 +361,7 @@ void LayoutBox::StyleWillChange(StyleDifference diff,
// The background of the root element or the body element could propagate up
// to the canvas. Just dirty the entire canvas when our style changes
// substantially.
- if ((diff.NeedsFullPaintInvalidation() || diff.NeedsLayout()) &&
- GetNode() &&
+ if ((diff.NeedsPaintInvalidation() || diff.NeedsLayout()) && GetNode() &&
(IsDocumentElement() || IsA<HTMLBodyElement>(*GetNode()))) {
View()->SetShouldDoFullPaintInvalidation();
}
@@ -258,7 +376,7 @@ void LayoutBox::StyleWillChange(StyleDifference diff,
// We're about to go out of flow. Before that takes place, we need to
// mark the current containing block chain for preferred widths
// recalculation.
- SetNeedsLayoutAndPrefWidthsRecalc(
+ SetNeedsLayoutAndIntrinsicWidthsRecalc(
layout_invalidation_reason::kStyleChange);
} else {
MarkContainerChainForLayout();
@@ -468,7 +586,6 @@ void LayoutBox::UpdateScrollSnapMappingAfterStyleChange(
const ComputedStyle& old_style) {
DCHECK(Style());
SnapCoordinator& snap_coordinator = GetDocument().GetSnapCoordinator();
-
// scroll-snap-type and scroll-padding invalidate the snap container.
if (old_style.GetScrollSnapType() != StyleRef().GetScrollSnapType() ||
old_style.ScrollPaddingBottom() != StyleRef().ScrollPaddingBottom() ||
@@ -487,6 +604,10 @@ void LayoutBox::UpdateScrollSnapMappingAfterStyleChange(
old_style.ScrollMarginTop() != StyleRef().ScrollMarginTop() ||
old_style.ScrollMarginRight() != StyleRef().ScrollMarginRight())
snap_coordinator.SnapAreaDidChange(*this, StyleRef().GetScrollSnapAlign());
+
+ // Transform invalidates the snap area.
+ if (old_style.Transform() != StyleRef().Transform())
+ snap_coordinator.SnapAreaDidChange(*this, StyleRef().GetScrollSnapAlign());
}
void LayoutBox::AddScrollSnapMapping() {
@@ -647,9 +768,9 @@ int LayoutBox::PixelSnappedScrollHeight() const {
PhysicalRect LayoutBox::ScrollRectToVisibleRecursive(
const PhysicalRect& absolute_rect,
- const WebScrollIntoViewParams& params) {
- DCHECK(params.GetScrollType() == kProgrammaticScroll ||
- params.GetScrollType() == kUserScroll);
+ mojom::blink::ScrollIntoViewParamsPtr params) {
+ DCHECK(params->type == mojom::blink::ScrollType::kProgrammatic ||
+ params->type == mojom::blink::ScrollType::kUser);
if (!GetFrameView())
return absolute_rect;
@@ -659,12 +780,9 @@ PhysicalRect LayoutBox::ScrollRectToVisibleRecursive(
// if the stop_at_main_frame_layout_viewport option is set. We do this so
// that we can allow a smooth "scroll and zoom" animation to do the final
// scroll in cases like scrolling a focused editable box into view.
- if (params.stop_at_main_frame_layout_viewport && IsGlobalRootScroller())
+ if (params->stop_at_main_frame_layout_viewport && IsGlobalRootScroller())
return absolute_rect;
- // Presumably the same issue as in setScrollTop. See crbug.com/343132.
- DisableCompositingQueryAsserts disabler;
-
PhysicalRect absolute_rect_to_scroll = absolute_rect;
if (absolute_rect_to_scroll.Width() <= 0)
absolute_rect_to_scroll.SetWidth(LayoutUnit(1));
@@ -677,11 +795,11 @@ PhysicalRect LayoutBox::ScrollRectToVisibleRecursive(
parent_box = ContainingBlock();
PhysicalRect absolute_rect_for_parent;
- if (!IsLayoutView() && HasOverflowClip()) {
+ if (!IsA<LayoutView>(this) && HasOverflowClip()) {
absolute_rect_for_parent =
GetScrollableArea()->ScrollIntoView(absolute_rect_to_scroll, params);
} else if (!parent_box && CanBeProgramaticallyScrolled()) {
- ScrollableArea* area_to_scroll = params.make_visible_in_visual_viewport
+ ScrollableArea* area_to_scroll = params->make_visible_in_visual_viewport
? GetFrameView()->GetScrollableArea()
: GetFrameView()->LayoutViewport();
absolute_rect_for_parent =
@@ -706,7 +824,7 @@ PhysicalRect LayoutBox::ScrollRectToVisibleRecursive(
// have any effect, so we avoid using the RootFrameViewport and explicitly
// scroll the visual viewport if we can. If not, we're done.
if (StyleRef().GetPosition() == EPosition::kFixed && Container() == View() &&
- params.make_visible_in_visual_viewport) {
+ params->make_visible_in_visual_viewport) {
if (GetFrame()->IsMainFrame()) {
// TODO(donnd): We should continue the recursion if we're in a subframe.
return GetFrame()->GetPage()->GetVisualViewport().ScrollIntoView(
@@ -718,11 +836,11 @@ PhysicalRect LayoutBox::ScrollRectToVisibleRecursive(
if (parent_box) {
return parent_box->ScrollRectToVisibleRecursive(absolute_rect_for_parent,
- params);
+ std::move(params));
} else if (GetFrame()->IsLocalRoot() && !GetFrame()->IsMainFrame()) {
if (AllowedToPropagateRecursiveScrollToParentFrame(params)) {
GetFrameView()->ScrollRectToVisibleInRemoteParent(
- absolute_rect_for_parent, params);
+ absolute_rect_for_parent, std::move(params));
}
}
@@ -767,67 +885,74 @@ void LayoutBox::UpdateAfterLayout() {
// e.g. an OOF-positioned object is laid out by an NG containing block, then
// Legacy, then NG again, NG won't use a stale layout result.
if (IsOutOfFlowPositioned() && !IsLayoutNGObject())
- cached_layout_result_.reset();
+ ClearLayoutResults();
}
bool LayoutBox::HasOverrideIntrinsicContentWidth() const {
- const auto& style = StyleRef();
- const IntrinsicLength& intrinsic_length = style.IntrinsicWidth();
- if (intrinsic_length.IsLegacy())
+ if (!ShouldApplySizeContainment())
return false;
- if (intrinsic_length.IsAuto()) {
- // If we have an overflow that is not 'visible' in this direction, then we
- // override the intrinsic length to be 0. Otherwise, it's the same as
- // legacy, meaning we don't override it.
- // https://drafts.csswg.org/css-sizing-4/#valdef-intrinsic-block-size-auto
- return style.OverflowX() != EOverflow::kVisible;
- }
- return true;
+ const Length& intrinsic_length = StyleRef().ContainIntrinsicSize().Width();
+ return !intrinsic_length.IsAuto();
}
bool LayoutBox::HasOverrideIntrinsicContentHeight() const {
- const auto& style = StyleRef();
- const IntrinsicLength& intrinsic_length = style.IntrinsicHeight();
- if (intrinsic_length.IsLegacy())
+ if (!ShouldApplySizeContainment())
return false;
- if (intrinsic_length.IsAuto()) {
- // If we have an overflow that is not 'visible' in this direction, then we
- // override the intrinsic length to be 0. Otherwise, it's the same as
- // legacy, meaning we don't override it.
- // https://drafts.csswg.org/css-sizing-4/#valdef-intrinsic-block-size-auto
- return style.OverflowY() != EOverflow::kVisible;
- }
- return true;
+ const Length& intrinsic_length = StyleRef().ContainIntrinsicSize().Height();
+ return !intrinsic_length.IsAuto();
}
LayoutUnit LayoutBox::OverrideIntrinsicContentWidth() const {
DCHECK(HasOverrideIntrinsicContentWidth());
const auto& style = StyleRef();
- const IntrinsicLength& intrinsic_length = style.IntrinsicWidth();
- DCHECK(!intrinsic_length.IsLegacy());
- if (intrinsic_length.IsAuto()) {
- DCHECK(style.OverflowX() != EOverflow::kVisible);
- return LayoutUnit();
- }
- DCHECK(intrinsic_length.GetLength().IsFixed());
- DCHECK_GE(intrinsic_length.GetLength().Value(), 0.f);
- return LayoutUnit(intrinsic_length.GetLength().Value());
+ const Length& intrinsic_length = style.ContainIntrinsicSize().Width();
+ DCHECK(!intrinsic_length.IsAuto());
+ DCHECK(intrinsic_length.IsFixed());
+ DCHECK_GE(intrinsic_length.Value(), 0.f);
+ return LayoutUnit(intrinsic_length.Value());
}
LayoutUnit LayoutBox::OverrideIntrinsicContentHeight() const {
DCHECK(HasOverrideIntrinsicContentHeight());
const auto& style = StyleRef();
- const IntrinsicLength& intrinsic_length = style.IntrinsicHeight();
- DCHECK(!intrinsic_length.IsLegacy());
- if (intrinsic_length.IsAuto()) {
- DCHECK(style.OverflowY() != EOverflow::kVisible);
- return LayoutUnit();
+ const Length& intrinsic_length = style.ContainIntrinsicSize().Height();
+ DCHECK(!intrinsic_length.IsAuto());
+ DCHECK(intrinsic_length.IsFixed());
+ DCHECK_GE(intrinsic_length.Value(), 0.f);
+ return LayoutUnit(intrinsic_length.Value());
+}
+
+LayoutUnit LayoutBox::DefaultIntrinsicContentInlineSize() const {
+ // If the intrinsic-inline-size is specified, then we shouldn't ever need to
+ // get here.
+ DCHECK(!HasOverrideIntrinsicContentLogicalWidth());
+
+ auto* select = DynamicTo<HTMLSelectElement>(GetNode());
+ if (UNLIKELY(select && select->UsesMenuList())) {
+ return MenuListIntrinsicInlineSize(*select, *this);
+ }
+ auto* input = DynamicTo<HTMLInputElement>(GetNode());
+ if (UNLIKELY(input && input->type() == input_type_names::kFile))
+ return FileUploadControlIntrinsicInlineSize(*input, *this);
+ return kIndefiniteSize;
+}
+
+LayoutUnit LayoutBox::DefaultIntrinsicContentBlockSize() const {
+ // If the intrinsic-block-size is specified, then we shouldn't ever need to
+ // get here.
+ DCHECK(!HasOverrideIntrinsicContentLogicalHeight());
+
+ if (const auto* select = DynamicTo<HTMLSelectElement>(GetNode())) {
+ if (select->UsesMenuList()) {
+ return MenuListIntrinsicBlockSize(*select, *this);
+ } else {
+ return ListBoxItemHeight(*select, *this) * select->ListBoxSize() -
+ ScrollbarLogicalHeight();
+ }
}
- DCHECK(intrinsic_length.GetLength().IsFixed());
- DCHECK_GE(intrinsic_length.GetLength().Value(), 0.f);
- return LayoutUnit(intrinsic_length.GetLength().Value());
+ return kIndefiniteSize;
}
LayoutUnit LayoutBox::LogicalHeightWithVisibleOverflow() const {
@@ -844,7 +969,7 @@ LayoutUnit LayoutBox::ConstrainLogicalWidthByMinMax(
LayoutUnit available_width,
const LayoutBlock* cb) const {
const ComputedStyle& style_to_use = StyleRef();
- if (!style_to_use.LogicalMaxWidth().IsMaxSizeNone())
+ if (!style_to_use.LogicalMaxWidth().IsNone())
logical_width = std::min(
logical_width,
ComputeLogicalWidthUsing(kMaxSize, style_to_use.LogicalMaxWidth(),
@@ -860,8 +985,7 @@ LayoutUnit LayoutBox::ConstrainLogicalHeightByMinMax(
// Note that the values 'min-content', 'max-content' and 'fit-content' should
// behave as the initial value if specified in the block direction.
const Length& logical_max_height = StyleRef().LogicalMaxHeight();
- if (!logical_max_height.IsMaxSizeNone() &&
- !logical_max_height.IsMinContent() &&
+ if (!logical_max_height.IsNone() && !logical_max_height.IsMinContent() &&
!logical_max_height.IsMaxContent() &&
!logical_max_height.IsFitContent()) {
LayoutUnit max_h = ComputeLogicalHeightUsing(kMaxSize, logical_max_height,
@@ -885,7 +1009,7 @@ LayoutUnit LayoutBox::ConstrainContentBoxLogicalHeightByMinMax(
// advantage of already knowing the current resolved percentage height
// to avoid recursing up through our containing blocks again to determine it.
const ComputedStyle& style_to_use = StyleRef();
- if (!style_to_use.LogicalMaxHeight().IsMaxSizeNone()) {
+ if (!style_to_use.LogicalMaxHeight().IsNone()) {
if (style_to_use.LogicalMaxHeight().IsPercent() &&
style_to_use.LogicalHeight().IsPercent()) {
LayoutUnit available_logical_height(
@@ -1083,9 +1207,9 @@ void LayoutBox::Autoscroll(const PhysicalOffset& position_in_root_frame) {
ScrollRectToVisibleRecursive(
PhysicalRect(absolute_position,
PhysicalSize(LayoutUnit(1), LayoutUnit(1))),
- WebScrollIntoViewParams(ScrollAlignment::kAlignToEdgeIfNeeded,
- ScrollAlignment::kAlignToEdgeIfNeeded,
- kUserScroll));
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::ToEdgeIfNeeded(), ScrollAlignment::ToEdgeIfNeeded(),
+ mojom::blink::ScrollType::kUser));
}
bool LayoutBox::CanAutoscroll() const {
@@ -1155,11 +1279,6 @@ LayoutBox* LayoutBox::FindAutoscrollable(LayoutObject* layout_object,
: nullptr;
}
-void LayoutBox::MayUpdateHoverWhenContentUnderMouseChanged(
- EventHandler& event_handler) {
- event_handler.MayUpdateHoverAfterScroll(AbsoluteBoundingBoxFloatRect());
-}
-
void LayoutBox::ScrollByRecursively(const ScrollOffset& delta) {
if (delta.IsZero() || !HasOverflowClip())
return;
@@ -1168,7 +1287,8 @@ void LayoutBox::ScrollByRecursively(const ScrollOffset& delta) {
DCHECK(scrollable_area);
ScrollOffset new_scroll_offset = scrollable_area->GetScrollOffset() + delta;
- scrollable_area->SetScrollOffset(new_scroll_offset, kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(new_scroll_offset,
+ mojom::blink::ScrollType::kProgrammatic);
// If this layer can't do the scroll we ask the next layer up that can
// scroll to try.
@@ -1336,7 +1456,7 @@ bool LayoutBox::MapContentsRectToBoxSpace(
}
bool LayoutBox::ContainedContentsScroll(const LayoutObject& contents) const {
- if (IsLayoutView() &&
+ if (IsA<LayoutView>(this) &&
contents.StyleRef().GetPosition() == EPosition::kFixed) {
return false;
}
@@ -1366,40 +1486,23 @@ bool LayoutBox::ApplyBoxClips(
return does_intersect;
}
-void LayoutBox::ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const {
- min_logical_width =
- MinPreferredLogicalWidth() - BorderAndPaddingLogicalWidth();
- max_logical_width =
- MaxPreferredLogicalWidth() - BorderAndPaddingLogicalWidth();
+MinMaxSizes LayoutBox::PreferredLogicalWidths() const {
+ NOTREACHED();
+ return MinMaxSizes();
}
-LayoutUnit LayoutBox::MinPreferredLogicalWidth() const {
- if (PreferredLogicalWidthsDirty()) {
-#if DCHECK_IS_ON()
- SetLayoutNeededForbiddenScope layout_forbidden_scope(
- const_cast<LayoutBox&>(*this));
-#endif
- const_cast<LayoutBox*>(this)->ComputePreferredLogicalWidths();
- DCHECK(!PreferredLogicalWidthsDirty());
- }
-
- return min_preferred_logical_width_;
-}
+void LayoutBox::UpdateCachedIntrinsicLogicalWidthsIfNeeded() {
+ if (!IntrinsicLogicalWidthsDirty())
+ return;
-DISABLE_CFI_PERF
-LayoutUnit LayoutBox::MaxPreferredLogicalWidth() const {
- if (PreferredLogicalWidthsDirty()) {
#if DCHECK_IS_ON()
- SetLayoutNeededForbiddenScope layout_forbidden_scope(
- const_cast<LayoutBox&>(*this));
+ SetLayoutNeededForbiddenScope layout_forbidden_scope(*this);
#endif
- const_cast<LayoutBox*>(this)->ComputePreferredLogicalWidths();
- DCHECK(!PreferredLogicalWidthsDirty());
- }
- return max_preferred_logical_width_;
+ intrinsic_logical_widths_ = ComputeIntrinsicLogicalWidths();
+ intrinsic_logical_widths_percentage_resolution_block_size_ =
+ LayoutUnit::Min();
+ ClearIntrinsicLogicalWidthsDirty();
}
LayoutUnit LayoutBox::OverrideLogicalWidth() const {
@@ -1771,7 +1874,7 @@ bool LayoutBox::GetBackgroundPaintedExtent(PhysicalRect& painted_extent) const {
// LayoutView is special in the sense that it expands to the whole canvas,
// thus can't be handled by this function.
- DCHECK(!IsLayoutView());
+ DCHECK(!IsA<LayoutView>(this));
PhysicalRect background_rect(PhysicalBorderBoxRect());
@@ -1901,7 +2004,7 @@ bool LayoutBox::ComputeBackgroundIsKnownToBeObscured() const {
if (!StyleRef().HasBackground())
return false;
// Root background painting is special.
- if (IsLayoutView())
+ if (IsA<LayoutView>(this))
return false;
// FIXME: box-shadow is painted while background painting.
if (StyleRef().BoxShadow())
@@ -2020,10 +2123,6 @@ void LayoutBox::SizeChanged() {
// object for paint invalidation.
if (!NeedsLayout())
SetShouldCheckForPaintInvalidation();
-
- if (auto* element = DynamicTo<Element>(GetNode())) {
- element->SetNeedsResizeObserverUpdate();
- }
}
bool LayoutBox::IntersectsVisibleViewport() const {
@@ -2089,12 +2188,33 @@ PhysicalRect LayoutBox::OverflowClipRect(
if (HasOverflowClip())
ExcludeScrollbars(clip_rect, overlay_scrollbar_clip_behavior);
- if (HasControlClip())
- clip_rect.Intersect(ControlClipRect(location));
+ auto* input = DynamicTo<HTMLInputElement>(GetNode());
+ if (UNLIKELY(input)) {
+ // As for LayoutButton, ControlClip is to for not BUTTONs but INPUT
+ // buttons for IE/Firefox compatibility.
+ if (IsTextField() || IsLayoutButton()) {
+ DCHECK(HasControlClip());
+ PhysicalRect control_clip = PhysicalPaddingBoxRect();
+ control_clip.Move(location);
+ clip_rect.Intersect(control_clip);
+ }
+ } else if (UNLIKELY(IsMenuList(this))) {
+ DCHECK(HasControlClip());
+ PhysicalRect control_clip = PhysicalContentBoxRect();
+ control_clip.Move(location);
+ clip_rect.Intersect(control_clip);
+ } else {
+ DCHECK(!HasControlClip());
+ }
return clip_rect;
}
+bool LayoutBox::HasControlClip() const {
+ return UNLIKELY(IsTextField() || IsFileUploadControl() || IsMenuList(this) ||
+ (IsLayoutButton() && IsA<HTMLInputElement>(GetNode())));
+}
+
void LayoutBox::ExcludeScrollbars(
PhysicalRect& rect,
OverlayScrollbarClipBehavior overlay_scrollbar_clip_behavior) const {
@@ -2343,6 +2463,17 @@ void LayoutBox::DirtyLineBoxes(bool full_layout) {
}
}
+bool LayoutBox::HasInlineFragments() const {
+ if (!IsInLayoutNGInlineFormattingContext())
+ return inline_box_wrapper_;
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return first_paint_fragment_;
+ // TODO(yosin): We should use |first_fragment_item_index_|.
+ NGInlineCursor cursor;
+ cursor.MoveTo(*this);
+ return cursor;
+}
+
void LayoutBox::SetFirstInlineFragment(NGPaintFragment* fragment) {
CHECK(IsInLayoutNGInlineFormattingContext()) << *this;
// TODO(yosin): Once we remove |NGPaintFragment|, we should get rid of
@@ -2361,7 +2492,9 @@ void LayoutBox::SetFirstInlineFragmentItemIndex(wtf_size_t index) {
CHECK(IsInLayoutNGInlineFormattingContext()) << *this;
DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
DCHECK_NE(index, 0u);
- first_fragment_item_index_ = index;
+ // TDOO(yosin): Once we update all |LayoutObject::FirstInlineFragment()|,
+ // we should enable below.
+ // first_fragment_item_index_ = index;
}
void LayoutBox::InLayoutNGInlineFormattingContextWillChange(bool new_value) {
@@ -2372,33 +2505,76 @@ void LayoutBox::InLayoutNGInlineFormattingContextWillChange(bool new_value) {
DCHECK(new_value ? !first_paint_fragment_ : !inline_box_wrapper_);
}
-void LayoutBox::SetCachedLayoutResult(const NGLayoutResult& layout_result,
- const NGBreakToken* break_token) {
- DCHECK_EQ(layout_result.Status(), NGLayoutResult::kSuccess);
+void LayoutBox::SetCachedLayoutResult(
+ scoped_refptr<const NGLayoutResult> result) {
+ DCHECK(!result->PhysicalFragment().BreakToken());
+ DCHECK(!result->IsSingleUse());
- if (break_token)
- return;
- if (layout_result.PhysicalFragment().BreakToken())
- return;
+ if (result->GetConstraintSpaceForCaching().CacheSlot() ==
+ NGCacheSlot::kMeasure) {
+ if (measure_result_)
+ InvalidateItems(*measure_result_);
+ measure_result_ = result;
+ // When setting the "measure" result we also set the "layout" result.
+ }
- ClearCachedLayoutResult();
- cached_layout_result_ = &layout_result;
+ AddLayoutResult(std::move(result), 0);
}
-void LayoutBox::ClearCachedLayoutResult() {
- if (!cached_layout_result_)
- return;
+void LayoutBox::AddLayoutResult(scoped_refptr<const NGLayoutResult> result,
+ wtf_size_t index) {
+ DCHECK_EQ(result->Status(), NGLayoutResult::kSuccess);
+ if (index != WTF::kNotFound)
+ ShrinkLayoutResults(index);
+ layout_results_.push_back(std::move(result));
+}
+void LayoutBox::ClearLayoutResults() {
+ if (measure_result_)
+ InvalidateItems(*measure_result_);
+ measure_result_ = nullptr;
+
+ ShrinkLayoutResults(0);
+}
+
+void LayoutBox::ShrinkLayoutResults(wtf_size_t results_to_keep) {
+ DCHECK_GE(layout_results_.size(), results_to_keep);
// Invalidate if inline |DisplayItemClient|s will be destroyed.
- if (const auto* box_fragment = DynamicTo<NGPhysicalBoxFragment>(
- &cached_layout_result_->PhysicalFragment())) {
- if (box_fragment->HasItems()) {
- DCHECK_EQ(this, box_fragment->GetLayoutObject());
- ObjectPaintInvalidator(*this).SlowSetPaintingLayerNeedsRepaint();
- }
- }
+ for (wtf_size_t i = results_to_keep; i < layout_results_.size(); i++)
+ InvalidateItems(*layout_results_[i]);
+ layout_results_.Shrink(results_to_keep);
+}
+
+void LayoutBox::InvalidateItems(const NGLayoutResult& result) {
+ // Invalidate if inline |DisplayItemClient|s will be destroyed.
+ const auto& box_fragment =
+ To<NGPhysicalBoxFragment>(result.PhysicalFragment());
+ if (!box_fragment.HasItems())
+ return;
+
+ DCHECK_EQ(this, box_fragment.GetLayoutObject());
+ ObjectPaintInvalidator(*this).SlowSetPaintingLayerNeedsRepaint();
+}
+
+const NGLayoutResult* LayoutBox::GetCachedLayoutResult() const {
+ if (layout_results_.IsEmpty())
+ return nullptr;
+ // Only return re-usable results.
+ const NGLayoutResult* result = layout_results_[0].get();
+ if (result->IsSingleUse())
+ return nullptr;
+ DCHECK_EQ(layout_results_.size(), 1u);
+ return result;
+}
+
+const NGLayoutResult* LayoutBox::GetCachedMeasureResult() const {
+ if (!measure_result_)
+ return nullptr;
+
+ if (measure_result_->IsSingleUse())
+ return nullptr;
- cached_layout_result_ = nullptr;
+ return measure_result_.get();
}
scoped_refptr<const NGLayoutResult> LayoutBox::CachedLayoutResult(
@@ -2409,10 +2585,12 @@ scoped_refptr<const NGLayoutResult> LayoutBox::CachedLayoutResult(
NGLayoutCacheStatus* out_cache_status) {
*out_cache_status = NGLayoutCacheStatus::kNeedsLayout;
- if (!RuntimeEnabledFeatures::LayoutNGFragmentCachingEnabled())
- return nullptr;
+ const NGLayoutResult* cached_layout_result =
+ new_space.CacheSlot() == NGCacheSlot::kLayout &&
+ !layout_results_.IsEmpty()
+ ? GetCachedLayoutResult()
+ : GetCachedMeasureResult();
- const NGLayoutResult* cached_layout_result = GetCachedLayoutResult();
if (!cached_layout_result)
return nullptr;
@@ -2509,8 +2687,7 @@ scoped_refptr<const NGLayoutResult> LayoutBox::CachedLayoutResult(
bool is_exclusion_space_equal =
new_space.ExclusionSpace() == old_space.ExclusionSpace();
- bool is_new_formatting_context =
- physical_fragment.IsBlockFormattingContextRoot();
+ bool is_new_formatting_context = physical_fragment.IsFormattingContextRoot();
// If a node *doesn't* establish a new formatting context it may be affected
// by floats, or clearance.
@@ -2545,7 +2722,7 @@ scoped_refptr<const NGLayoutResult> LayoutBox::CachedLayoutResult(
// "simplified" layout then abort now.
*out_cache_status = cache_status;
if (*out_cache_status == NGLayoutCacheStatus::kNeedsSimplifiedLayout)
- return nullptr;
+ return cached_layout_result;
physical_fragment.CheckType();
@@ -2587,11 +2764,29 @@ scoped_refptr<const NGLayoutResult> LayoutBox::CachedLayoutResult(
bfc_block_offset, block_offset_delta));
if (needs_cached_result_update)
- SetCachedLayoutResult(*new_result, break_token);
+ SetCachedLayoutResult(new_result);
return new_result;
}
+const NGPhysicalBoxFragment* LayoutBox::GetPhysicalFragment(
+ wtf_size_t index) const {
+ return &To<NGPhysicalBoxFragment>(layout_results_[index]->PhysicalFragment());
+}
+
+const FragmentData* LayoutBox::FragmentDataFromPhysicalFragment(
+ const NGPhysicalBoxFragment& physical_fragment) const {
+ const FragmentData* fragment_data = &FirstFragment();
+ for (const auto& result : layout_results_) {
+ if (&result->PhysicalFragment() == &physical_fragment)
+ return fragment_data;
+ DCHECK(fragment_data->NextFragment());
+ fragment_data = fragment_data->NextFragment();
+ }
+ NOTREACHED();
+ return fragment_data;
+}
+
void LayoutBox::PositionLineBox(InlineBox* box) {
if (IsOutOfFlowPositioned()) {
// Cache the x position only if we were an INLINE type originally.
@@ -2772,27 +2967,6 @@ bool LayoutBox::NeedsForcedBreakBefore(
return IsForcedFragmentainerBreakValue(break_value);
}
-bool LayoutBox::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const {
- if (HasNonCompositedScrollbars() || IsSelected() ||
- HasBoxDecorationBackground() || StyleRef().HasBoxDecorations() ||
- StyleRef().HasVisualOverflowingEffect())
- return false;
-
- // Both mask and clip-path generates drawing display items that depends on
- // the size of the box.
- if (HasMask() || HasClipPath())
- return false;
-
- // If the box paints into its own backing, we can assume that it's painting
- // may have some effect. For example, honoring the border-radius clip on
- // a composited child paints into a mask for an otherwise non-painting
- // element, because children of that element will require the mask.
- if (HasLayer() && Layer()->GetCompositingState() == kPaintsIntoOwnBacking)
- return false;
-
- return true;
-}
-
PhysicalRect LayoutBox::LocalVisualRectIgnoringVisibility() const {
return PhysicalSelfVisualOverflowRect();
}
@@ -2900,10 +3074,10 @@ bool LayoutBox::MapToVisualRectInAncestorSpaceInternal(
return true;
}
- if (container->IsLayoutView()) {
+ if (auto* layout_view = DynamicTo<LayoutView>(container)) {
bool use_fixed_position_adjustment =
position == EPosition::kFixed && container == ancestor;
- return ToLayoutView(container)->MapToVisualRectInAncestorSpaceInternal(
+ return layout_view->MapToVisualRectInAncestorSpaceInternal(
ancestor, transform_state, use_fixed_position_adjustment ? kIsFixed : 0,
visual_rect_flags);
} else {
@@ -2926,7 +3100,7 @@ void LayoutBox::InflateVisualRectForFilter(
static bool ShouldRecalculateMinMaxWidthsAffectedByAncestor(
const LayoutBox* box) {
- if (box->PreferredLogicalWidthsDirty()) {
+ if (box->IntrinsicLogicalWidthsDirty()) {
// If the preferred widths are already dirty at this point (during layout),
// it actually means that we never need to calculate them, since that should
// have been carried out by an ancestor that's sized based on preferred
@@ -2937,7 +3111,7 @@ static bool ShouldRecalculateMinMaxWidthsAffectedByAncestor(
}
if (const LayoutBox* containing_block = box->ContainingBlock()) {
if (containing_block->NeedsPreferredWidthsRecalculation() &&
- !containing_block->PreferredLogicalWidthsDirty()) {
+ !containing_block->IntrinsicLogicalWidthsDirty()) {
// If our containing block also has min/max widths that are affected by
// the ancestry, we have already dealt with this object as well. Avoid
// unnecessary work and O(n^2) time complexity.
@@ -2956,14 +3130,14 @@ void LayoutBox::UpdateLogicalWidth() {
// bottom-up, but that's not always the case), so since the containing
// block size may have changed, we need to recalculate the min/max widths
// of this object, and every child that has the same issue, recursively.
- SetPreferredLogicalWidthsDirty(kMarkOnlyThis);
+ SetIntrinsicLogicalWidthsDirty(kMarkOnlyThis);
// Since all this takes place during actual layout, instead of being part
// of min/max the width calculation machinery, we need to enter said
- // machinery here, to make sure that what was dirtied is actualy
+ // machinery here, to make sure that what was dirtied is actually
// recalculated. Leaving things dirty would mean that any subsequent
// dirtying of descendants would fail.
- ComputePreferredLogicalWidths();
+ UpdateCachedIntrinsicLogicalWidthsIfNeeded();
}
}
@@ -3058,7 +3232,7 @@ void LayoutBox::ComputeLogicalWidth(
if (treat_as_replaced) {
computed_values.extent_ = std::max(
ComputeReplacedLogicalWidth() + BorderAndPaddingLogicalWidth(),
- MinPreferredLogicalWidth());
+ PreferredLogicalWidths().min_size);
}
return;
}
@@ -3163,33 +3337,27 @@ LayoutUnit LayoutBox::FillAvailableMeasure(LayoutUnit available_logical_width,
DISABLE_CFI_PERF
LayoutUnit LayoutBox::ComputeIntrinsicLogicalWidthUsing(
const Length& logical_width_length,
- LayoutUnit available_logical_width,
- LayoutUnit border_and_padding) const {
+ LayoutUnit available_logical_width) const {
if (logical_width_length.IsFillAvailable()) {
if (!IsA<HTMLMarqueeElement>(GetNode())) {
UseCounter::Count(GetDocument(),
WebFeature::kCSSFillAvailableLogicalWidth);
}
- return std::max(border_and_padding,
+ return std::max(BorderAndPaddingLogicalWidth(),
FillAvailableMeasure(available_logical_width));
}
- LayoutUnit min_logical_width;
- LayoutUnit max_logical_width;
- ComputeIntrinsicLogicalWidths(min_logical_width, max_logical_width);
+ MinMaxSizes sizes = IntrinsicLogicalWidths();
if (logical_width_length.IsMinContent())
- return min_logical_width + border_and_padding;
+ return sizes.min_size;
if (logical_width_length.IsMaxContent())
- return max_logical_width + border_and_padding;
+ return sizes.max_size;
if (logical_width_length.IsFitContent()) {
- min_logical_width += border_and_padding;
- max_logical_width += border_and_padding;
- return std::max(min_logical_width,
- std::min(max_logical_width,
- FillAvailableMeasure(available_logical_width)));
+ return sizes.ClampSizeToMinAndMax(
+ FillAvailableMeasure(available_logical_width));
}
NOTREACHED();
@@ -3214,9 +3382,10 @@ LayoutUnit LayoutBox::ComputeLogicalWidthUsing(
ValueForLength(logical_width, available_logical_width));
}
- if (logical_width.IsIntrinsic())
- return ComputeIntrinsicLogicalWidthUsing(
- logical_width, available_logical_width, BorderAndPaddingLogicalWidth());
+ if (logical_width.IsIntrinsic()) {
+ return ComputeIntrinsicLogicalWidthUsing(logical_width,
+ available_logical_width);
+ }
LayoutUnit margin_start;
LayoutUnit margin_end;
@@ -3238,9 +3407,9 @@ LayoutUnit LayoutBox::ComputeLogicalWidthUsing(
// TODO(crbug.com/710026): Remove const_cast
LayoutUnit w = LogicalWidth();
const_cast<LayoutBox*>(this)->SetLogicalWidth(LayoutUnit());
+ MinMaxSizes preferred_logical_widths = PreferredLogicalWidths();
LayoutUnit result =
- std::max(MinPreferredLogicalWidth(),
- std::min(MaxPreferredLogicalWidth(), logical_width_result));
+ preferred_logical_widths.ClampSizeToMinAndMax(logical_width_result);
const_cast<LayoutBox*>(this)->SetLogicalWidth(w);
return result;
}
@@ -3513,10 +3682,16 @@ void LayoutBox::ComputeLogicalHeight(
if (HasOverrideIntrinsicContentLogicalHeight()) {
height = OverrideIntrinsicContentLogicalHeight() +
BorderAndPaddingLogicalHeight() + ScrollbarLogicalHeight();
- } else if (ShouldApplySizeContainment() && !IsLayoutGrid()) {
- height = BorderAndPaddingLogicalHeight() + ScrollbarLogicalHeight();
} else {
- height = LogicalHeight();
+ LayoutUnit default_height = DefaultIntrinsicContentBlockSize();
+ if (default_height != kIndefiniteSize) {
+ height = default_height + BorderAndPaddingLogicalHeight() +
+ ScrollbarLogicalHeight();
+ } else if (ShouldApplySizeContainment() && !IsLayoutGrid()) {
+ height = BorderAndPaddingLogicalHeight() + ScrollbarLogicalHeight();
+ } else {
+ height = LogicalHeight();
+ }
}
ComputeLogicalHeight(height, LogicalTop(), computed_values);
}
@@ -3564,22 +3739,13 @@ void LayoutBox::ComputeLogicalHeight(
return;
}
- // FIXME: Account for writing-mode in flexible boxes.
- // https://bugs.webkit.org/show_bug.cgi?id=46418
- bool in_horizontal_box =
- Parent()->IsDeprecatedFlexibleBox() &&
- Parent()->StyleRef().BoxOrient() == EBoxOrient::kHorizontal;
- bool stretching =
- Parent()->StyleRef().BoxAlign() == EBoxAlignment::kStretch;
- bool treat_as_replaced =
- ShouldComputeSizeAsReplaced() && (!in_horizontal_box || !stretching);
bool check_min_max_height = false;
// The parent box is flexing us, so it has increased or decreased our
// height. We have to grab our cached flexible height.
if (HasOverrideLogicalHeight()) {
h = Length::Fixed(OverrideLogicalHeight());
- } else if (treat_as_replaced) {
+ } else if (ShouldComputeSizeAsReplaced()) {
h = Length::Fixed(ComputeReplacedLogicalHeight() +
BorderAndPaddingLogicalHeight());
} else {
@@ -3587,16 +3753,6 @@ void LayoutBox::ComputeLogicalHeight(
check_min_max_height = true;
}
- // Block children of horizontal flexible boxes fill the height of the box.
- // FIXME: Account for writing-mode in flexible boxes.
- // https://bugs.webkit.org/show_bug.cgi?id=46418
- if (h.IsAuto() && in_horizontal_box &&
- ToLayoutDeprecatedFlexibleBox(Parent())->IsStretchingChildren()) {
- h = Length::Fixed(ParentBox()->ContentLogicalHeight() - MarginBefore() -
- MarginAfter());
- check_min_max_height = false;
- }
-
LayoutUnit height_result;
if (check_min_max_height) {
height_result = ComputeLogicalHeightUsing(
@@ -3793,7 +3949,7 @@ LayoutUnit LayoutBox::ContainingBlockLogicalHeightForPercentageResolution(
const LayoutBox* containing_block_child = this;
bool skipped_auto_height_containing_block = false;
LayoutUnit root_margin_border_padding_height;
- while (!cb->IsLayoutView() &&
+ while (!IsA<LayoutView>(cb) &&
(IsHorizontalWritingMode() == cb->IsHorizontalWritingMode() &&
SkipContainingBlockForPercentHeightCalculation(cb))) {
if ((cb->IsBody() || cb->IsDocumentElement()) &&
@@ -3931,7 +4087,7 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalWidthRespectingMinMaxWidth(
LayoutUnit max_logical_width =
(should_compute_preferred == kComputePreferred &&
StyleRef().LogicalMaxWidth().IsPercentOrCalc()) ||
- StyleRef().LogicalMaxWidth().IsMaxSizeNone()
+ StyleRef().LogicalMaxWidth().IsNone()
? logical_width
: ComputeReplacedLogicalWidthUsing(kMaxSize,
StyleRef().LogicalMaxWidth());
@@ -3955,8 +4111,7 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalWidthUsing(
// MinContent/MaxContent don't need the availableLogicalWidth argument.
LayoutUnit available_logical_width;
return ComputeIntrinsicLogicalWidthUsing(logical_width,
- available_logical_width,
- BorderAndPaddingLogicalWidth()) -
+ available_logical_width) -
BorderAndPaddingLogicalWidth();
}
case Length::kFitContent:
@@ -3978,8 +4133,7 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalWidthUsing(
// FIXME: Handle cases when containing block width is calculated or
// viewport percent. https://bugs.webkit.org/show_bug.cgi?id=91071
if (logical_width.IsIntrinsic())
- return ComputeIntrinsicLogicalWidthUsing(
- logical_width, cw, BorderAndPaddingLogicalWidth()) -
+ return ComputeIntrinsicLogicalWidthUsing(logical_width, cw) -
BorderAndPaddingLogicalWidth();
if (cw > 0 || (!cw && (container_logical_width.IsFixed() ||
container_logical_width.IsPercentOrCalc())))
@@ -3988,7 +4142,7 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalWidthUsing(
return LayoutUnit();
}
case Length::kAuto:
- case Length::kMaxSizeNone:
+ case Length::kNone:
return IntrinsicLogicalWidth();
case Length::kExtendToZoom:
case Length::kDeviceWidth:
@@ -4025,6 +4179,11 @@ bool LayoutBox::LogicalHeightComputesAsNone(SizeType size_type) const {
if (logical_height == initial_logical_height)
return true;
+ if (logical_height.IsPercentOrCalc() &&
+ HasOverrideContainingBlockContentLogicalHeight() &&
+ OverrideContainingBlockContentLogicalHeight() == kIndefiniteSize)
+ return true;
+
// CustomLayout items can resolve their percentages against an available or
// percentage size override.
if (IsCustomItem() && (HasOverrideContainingBlockContentLogicalHeight() ||
@@ -4114,7 +4273,7 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalHeightUsing(
// FIXME: This needs to be made writing-mode-aware. If the cell and
// image are perpendicular writing-modes, this isn't right.
// https://bugs.webkit.org/show_bug.cgi?id=46997
- while (cb && !cb->IsLayoutView() &&
+ while (!IsA<LayoutView>(cb) &&
(cb->StyleRef().LogicalHeight().IsAuto() ||
cb->StyleRef().LogicalHeight().IsPercentOrCalc())) {
if (cb->IsTableCell()) {
@@ -4173,10 +4332,10 @@ LayoutUnit LayoutBox::AvailableLogicalHeight(
LayoutUnit LayoutBox::AvailableLogicalHeightUsing(
const Length& h,
AvailableLogicalHeightType height_type) const {
- if (IsLayoutView()) {
+ if (auto* layout_view = DynamicTo<LayoutView>(this)) {
return LayoutUnit(IsHorizontalWritingMode()
- ? ToLayoutView(this)->GetFrameView()->Size().Height()
- : ToLayoutView(this)->GetFrameView()->Size().Width());
+ ? layout_view->GetFrameView()->Size().Height()
+ : layout_view->GetFrameView()->Size().Width());
}
// We need to stop here, since we don't want to increase the height of the
@@ -4192,10 +4351,17 @@ LayoutUnit LayoutBox::AvailableLogicalHeightUsing(
return LogicalHeight() - BorderAndPaddingLogicalHeight();
}
- if (IsFlexItem()) {
- const LayoutFlexibleBox& flex_box = ToLayoutFlexibleBox(*Parent());
- if (flex_box.UseOverrideLogicalHeightForPerentageResolution(*this))
- return OverrideContentLogicalHeight();
+ if (IsFlexItemIncludingNG()) {
+ if (IsFlexItem()) {
+ const LayoutFlexibleBox& flex_box = ToLayoutFlexibleBox(*Parent());
+ if (flex_box.UseOverrideLogicalHeightForPerentageResolution(*this))
+ return OverrideContentLogicalHeight();
+ } else if (GetCachedLayoutResult()) {
+ const NGConstraintSpace& space =
+ GetCachedLayoutResult()->GetConstraintSpaceForCaching();
+ if (space.IsFixedBlockSize() && !space.IsFixedBlockSizeIndefinite())
+ return space.AvailableSize().block_size;
+ }
}
if (h.IsPercentOrCalc() && IsOutOfFlowPositioned()) {
@@ -4271,9 +4437,9 @@ LayoutUnit LayoutBox::ContainingBlockLogicalWidthForPositioned(
return ContainingBlockLogicalHeightForPositioned(containing_block, false);
// Use viewport as container for top-level fixed-position elements.
- if (StyleRef().GetPosition() == EPosition::kFixed &&
- containing_block->IsLayoutView() && !GetDocument().Printing()) {
- const LayoutView* view = ToLayoutView(containing_block);
+ const auto* view = DynamicTo<LayoutView>(containing_block);
+ if (StyleRef().GetPosition() == EPosition::kFixed && view &&
+ !GetDocument().Printing()) {
if (LocalFrameView* frame_view = view->GetFrameView()) {
// Don't use visibleContentRect since the PaintLayer's size has not been
// set yet.
@@ -4342,9 +4508,9 @@ LayoutUnit LayoutBox::ContainingBlockLogicalHeightForPositioned(
return ContainingBlockLogicalWidthForPositioned(containing_block, false);
// Use viewport as container for top-level fixed-position elements.
- if (StyleRef().GetPosition() == EPosition::kFixed &&
- containing_block->IsLayoutView() && !GetDocument().Printing()) {
- const LayoutView* view = ToLayoutView(containing_block);
+ const auto* view = DynamicTo<LayoutView>(containing_block);
+ if (StyleRef().GetPosition() == EPosition::kFixed && view &&
+ !GetDocument().Printing()) {
if (LocalFrameView* frame_view = view->GetFrameView()) {
// Don't use visibleContentRect since the PaintLayer's size has not been
// set yet.
@@ -4368,7 +4534,7 @@ LayoutUnit LayoutBox::ContainingBlockLogicalHeightForPositioned(
const LayoutInline* flow = ToLayoutInline(containing_block);
// If the containing block is empty, return a height of 0.
- if (flow->IsEmpty())
+ if (!flow->HasInlineFragments())
return LayoutUnit();
LayoutUnit height_result;
@@ -4583,7 +4749,7 @@ void LayoutBox::ComputePositionedLogicalWidth(
margin_logical_right, computed_values);
// Calculate constraint equation values for 'max-width' case.
- if (!StyleRef().LogicalMaxWidth().IsMaxSizeNone()) {
+ if (!StyleRef().LogicalMaxWidth().IsNone()) {
LogicalExtentComputedValues max_values;
ComputePositionedLogicalWidthUsing(
@@ -4653,13 +4819,9 @@ void LayoutBox::ComputeLogicalLeftPositionedOffset(
LayoutUnit LayoutBox::ShrinkToFitLogicalWidth(
LayoutUnit available_logical_width,
LayoutUnit borders_plus_padding) const {
- LayoutUnit preferred_logical_width =
- MaxPreferredLogicalWidth() - borders_plus_padding;
- LayoutUnit preferred_min_logical_width =
- MinPreferredLogicalWidth() - borders_plus_padding;
- return std::min(
- std::max(preferred_min_logical_width, available_logical_width),
- preferred_logical_width);
+ MinMaxSizes sizes = PreferredLogicalWidths();
+ sizes -= borders_plus_padding;
+ return sizes.ShrinkToFit(available_logical_width);
}
void LayoutBox::ComputePositionedLogicalWidthUsing(
@@ -4678,16 +4840,16 @@ void LayoutBox::ComputePositionedLogicalWidthUsing(
DCHECK(width_size_type == kMinSize ||
width_size_type == kMainOrPreferredSize || !logical_width.IsAuto());
- if (width_size_type == kMinSize && logical_width.IsAuto())
+ if (width_size_type == kMinSize && logical_width.IsAuto()) {
logical_width_value = LayoutUnit();
- else if (logical_width.IsIntrinsic())
- logical_width_value =
- ComputeIntrinsicLogicalWidthUsing(
- logical_width, container_logical_width, borders_plus_padding) -
- borders_plus_padding;
- else
+ } else if (logical_width.IsIntrinsic()) {
+ logical_width_value = ComputeIntrinsicLogicalWidthUsing(
+ logical_width, container_logical_width) -
+ borders_plus_padding;
+ } else {
logical_width_value = AdjustContentBoxLogicalWidthForBoxSizing(
ValueForLength(logical_width, container_logical_width));
+ }
// 'left' and 'right' cannot both be 'auto' because one would of been
// converted to the static position already
@@ -4996,8 +5158,7 @@ void LayoutBox::ComputePositionedLogicalHeight(
// Calculate constraint equation values for 'max-height' case.
const Length& logical_max_height = style_to_use.LogicalMaxHeight();
- if (!logical_max_height.IsMaxSizeNone() &&
- !logical_max_height.IsMinContent() &&
+ if (!logical_max_height.IsNone() && !logical_max_height.IsMinContent() &&
!logical_max_height.IsMaxContent() &&
!logical_max_height.IsFitContent()) {
LogicalExtentComputedValues max_values;
@@ -5695,7 +5856,7 @@ void LayoutBox::AddLayoutOverflow(const LayoutRect& rect) {
// For overflow clip objects, we don't want to propagate overflow into
// unreachable areas.
LayoutRect overflow_rect(rect);
- if (HasOverflowClip() || IsLayoutView()) {
+ if (HasOverflowClip() || IsA<LayoutView>(this)) {
// Overflow is in the block's coordinate space and thus is flipped for
// vertical-rl writing
// mode. At this stage that is actually a simplification, since we can
@@ -5813,7 +5974,7 @@ bool LayoutBox::HasUnsplittableScrollingOverflow() const {
// world and is what we used to do in the old model anyway.
return !StyleRef().LogicalHeight().IsIntrinsicOrAuto() ||
(!StyleRef().LogicalMaxHeight().IsIntrinsicOrAuto() &&
- !StyleRef().LogicalMaxHeight().IsMaxSizeNone() &&
+ !StyleRef().LogicalMaxHeight().IsNone() &&
(!StyleRef().LogicalMaxHeight().IsPercentOrCalc() ||
PercentageLogicalHeightIsResolvable())) ||
(!StyleRef().LogicalMinHeight().IsIntrinsicOrAuto() &&
@@ -6029,7 +6190,7 @@ static void MarkBoxForRelayoutAfterSplit(LayoutBox* box) {
ToInterface<LayoutNGTableSectionInterface>(box)->SetNeedsCellRecalc();
}
- box->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ box->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAnonymousBlockChange);
}
@@ -6336,11 +6497,11 @@ void LayoutBox::ReassignSnapAreas(LayoutBox& new_container) {
}
bool LayoutBox::AllowedToPropagateRecursiveScrollToParentFrame(
- const WebScrollIntoViewParams& params) {
+ const mojom::blink::ScrollIntoViewParamsPtr& params) {
if (!GetFrameView()->SafeToPropagateScrollToParent())
return false;
- if (params.GetScrollType() != kProgrammaticScroll)
+ if (params->type != mojom::blink::ScrollType::kProgrammatic)
return true;
return !GetDocument().IsVerticalScrollEnforced();
@@ -6420,7 +6581,7 @@ TextDirection LayoutBox::ResolvedDirection() const {
NGInlineCursor cursor;
cursor.MoveTo(*this);
if (cursor)
- return cursor.CurrentResolvedDirection();
+ return cursor.Current().ResolvedDirection();
}
if (InlineBoxWrapper())
return InlineBoxWrapper()->Direction();
@@ -6428,4 +6589,15 @@ TextDirection LayoutBox::ResolvedDirection() const {
return StyleRef().Direction();
}
+bool LayoutBox::NeedsScrollNode(
+ CompositingReasons direct_compositing_reasons) const {
+ if (!HasOverflowClip())
+ return false;
+
+ if (direct_compositing_reasons & CompositingReason::kRootScroller)
+ return true;
+
+ return GetScrollableArea()->ScrollsOverflow();
+}
+
} // namespace blink