summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/layout/layout_list_item.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/layout/layout_list_item.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_item.cc147
1 files changed, 77 insertions, 70 deletions
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_list_item.cc b/chromium/third_party/blink/renderer/core/layout/layout_list_item.cc
index 6f882e11a4a..df0dd904451 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_list_item.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_list_item.cc
@@ -36,7 +36,6 @@ namespace blink {
LayoutListItem::LayoutListItem(Element* element)
: LayoutBlockFlow(element),
- marker_(nullptr),
need_block_direction_align_(false) {
SetInline(false);
@@ -51,13 +50,7 @@ void LayoutListItem::StyleDidChange(StyleDifference diff,
StyleImage* current_image = StyleRef().ListStyleImage();
if (StyleRef().ListStyleType() != EListStyleType::kNone ||
(current_image && !current_image->ErrorOccurred())) {
- if (!marker_)
- marker_ = LayoutListMarker::CreateAnonymous(this);
- marker_->ListItemStyleDidChange();
NotifyOfSubtreeChange();
- } else if (marker_) {
- marker_->Destroy();
- marker_ = nullptr;
}
StyleImage* old_image = old_style ? old_style->ListStyleImage() : nullptr;
@@ -70,11 +63,6 @@ void LayoutListItem::StyleDidChange(StyleDifference diff,
}
void LayoutListItem::WillBeDestroyed() {
- if (marker_) {
- marker_->Destroy();
- marker_ = nullptr;
- }
-
LayoutBlockFlow::WillBeDestroyed();
if (Style() && StyleRef().ListStyleImage())
@@ -94,7 +82,8 @@ void LayoutListItem::WillBeRemovedFromTree() {
}
void LayoutListItem::SubtreeDidChange() {
- if (!marker_)
+ LayoutListMarker* marker = Marker();
+ if (!marker)
return;
if (!UpdateMarkerLocation())
@@ -102,8 +91,8 @@ void LayoutListItem::SubtreeDidChange() {
// If the marker is inside we need to redo the preferred width calculations
// as the size of the item now includes the size of the list marker.
- if (marker_->IsInside())
- SetPreferredLogicalWidthsDirty();
+ if (marker->IsInsideListMarker())
+ SetIntrinsicLogicalWidthsDirty();
}
int LayoutListItem::Value() const {
@@ -112,13 +101,12 @@ int LayoutListItem::Value() const {
}
bool LayoutListItem::IsEmpty() const {
- return LastChild() == marker_;
+ return LastChild() == Marker();
}
namespace {
-LayoutObject* GetParentOfFirstLineBox(LayoutBlockFlow* curr,
- LayoutObject* marker) {
+LayoutObject* GetParentOfFirstLineBox(LayoutBlockFlow* curr) {
LayoutObject* first_child = curr->FirstChild();
if (!first_child)
return nullptr;
@@ -126,7 +114,7 @@ LayoutObject* GetParentOfFirstLineBox(LayoutBlockFlow* curr,
bool in_quirks_mode = curr->GetDocument().InQuirksMode();
for (LayoutObject* curr_child = first_child; curr_child;
curr_child = curr_child->NextSibling()) {
- if (curr_child == marker)
+ if (curr_child->IsOutsideListMarker())
continue;
if (curr_child->IsInline() &&
@@ -150,7 +138,7 @@ LayoutObject* GetParentOfFirstLineBox(LayoutBlockFlow* curr,
IsA<HTMLOListElement>(*curr_child->GetNode())))
break;
- LayoutObject* line_box = GetParentOfFirstLineBox(child_block_flow, marker);
+ LayoutObject* line_box = GetParentOfFirstLineBox(child_block_flow);
if (line_box)
return line_box;
}
@@ -186,21 +174,27 @@ void ForceLogicalHeight(LayoutObject& layout_object, const Length& height) {
// marker_container to 0px; else restore it to LogicalHeight of <li>.
bool LayoutListItem::PrepareForBlockDirectionAlign(
const LayoutObject* line_box_parent) {
- LayoutObject* marker_parent = marker_->Parent();
+ LayoutListMarker* marker = Marker();
+ LayoutObject* marker_parent = marker->Parent();
+ bool is_inside = marker->IsInsideListMarker();
// Deal with the situation of layout tree changed.
if (marker_parent && marker_parent->IsAnonymous()) {
+ bool marker_parent_has_lines =
+ line_box_parent && line_box_parent->IsDescendantOf(marker_parent);
// When list-position-style change from outside to inside, we need to
- // restore LogicalHeight to auto. So add IsInside().
- if (marker_->IsInside() || marker_->NextSibling()) {
+ // restore LogicalHeight to auto. So add is_inside.
+ if (is_inside || marker_parent_has_lines) {
// Set marker_container's LogicalHeight to auto.
if (marker_parent->StyleRef().LogicalHeight().IsZero())
ForceLogicalHeight(*marker_parent, Length());
- // If marker_parent isn't the ancestor of line_box_parent, marker might
- // generate a new empty line. We need to remove marker here.E.g:
- // <li><span><div>text<div><span></li>
- if (line_box_parent && !line_box_parent->IsDescendantOf(marker_parent)) {
- marker_->Remove();
+ // If marker_parent_has_lines and the marker is outside, we need to move
+ // the marker into another parent with 'height: 0' to avoid generating a
+ // new empty line in cases like <li><span><div>text<div><span></li>
+ // If the marker is inside and there are inline contents, we want them to
+ // share the same block container to avoid a line break between them.
+ if (is_inside != marker_parent_has_lines) {
+ marker->Remove();
marker_parent = nullptr;
}
} else if (line_box_parent) {
@@ -211,19 +205,18 @@ bool LayoutListItem::PrepareForBlockDirectionAlign(
// Create marker_container, set its height to 0px, and add it to li.
if (!marker_parent) {
LayoutObject* before_child = FirstNonMarkerChild(this);
- if (!marker_->IsInside() && before_child && !before_child->IsInline()) {
+ if (!is_inside && before_child && !before_child->IsInline()) {
// Create marker_container and set its LogicalHeight to 0px.
LayoutBlock* marker_container = CreateAnonymousBlock();
if (line_box_parent)
ForceLogicalHeight(*marker_container, Length::Fixed(0));
- marker_container->AddChild(marker_,
- FirstNonMarkerChild(marker_container));
+ marker_container->AddChild(marker, FirstNonMarkerChild(marker_container));
AddChild(marker_container, before_child);
} else {
- AddChild(marker_, before_child);
+ AddChild(marker, before_child);
}
- marker_->UpdateMarginsAndContent();
+ marker->UpdateMarginsAndContent();
return true;
}
return false;
@@ -241,13 +234,24 @@ static bool IsFirstLeafChild(LayoutObject* container, LayoutObject* child) {
}
bool LayoutListItem::UpdateMarkerLocation() {
- DCHECK(marker_);
+ DCHECK(Marker());
- LayoutObject* marker_parent = marker_->Parent();
+ LayoutListMarker* marker = Marker();
+ LayoutObject* marker_parent = marker->Parent();
LayoutObject* line_box_parent = nullptr;
- if (!marker_->IsInside())
- line_box_parent = GetParentOfFirstLineBox(this, marker_);
+ // Make sure a marker originated by a ::before or ::after precedes the
+ // generated contents.
+ if (IsPseudoElement()) {
+ LayoutObject* first_child = marker_parent->SlowFirstChild();
+ if (marker != first_child) {
+ marker->Remove();
+ AddChild(marker, first_child);
+ }
+ }
+
+ if (marker->IsOutsideListMarker())
+ line_box_parent = GetParentOfFirstLineBox(this);
if (line_box_parent && (line_box_parent->HasOverflowClip() ||
!line_box_parent->IsLayoutBlockFlow() ||
(line_box_parent->IsBox() &&
@@ -277,13 +281,13 @@ bool LayoutListItem::UpdateMarkerLocation() {
if (!marker_parent ||
(marker_parent != line_box_parent && NormalChildNeedsLayout())) {
- marker_->Remove();
- line_box_parent->AddChild(marker_, FirstNonMarkerChild(line_box_parent));
+ marker->Remove();
+ line_box_parent->AddChild(marker, FirstNonMarkerChild(line_box_parent));
// TODO(rhogan): line_box_parent and marker_parent may be deleted by
// AddChild, so they are not safe to reference here. Once we have a safe way
// of referencing them delete marker_parent if it is an empty anonymous
// block.
- marker_->UpdateMarginsAndContent();
+ marker->UpdateMarginsAndContent();
return true;
}
@@ -309,6 +313,7 @@ void LayoutListItem::ComputeVisualOverflow(bool recompute_floats) {
AddVisualOverflowFromFloats();
if (VisualOverflowRect() != previous_visual_overflow_rect) {
+ InvalidateIntersectionObserverCachedRects();
SetShouldCheckForPaintInvalidation();
GetFrameView()->SetIntersectionObservationState(LocalFrameView::kDesired);
}
@@ -327,7 +332,8 @@ void LayoutListItem::AlignMarkerInBlockDirection() {
// layout pass. So if there's no line box in line_box_parent make sure it
// back to its original position.
bool back_to_original_baseline = false;
- LayoutObject* line_box_parent = GetParentOfFirstLineBox(this, marker_);
+ LayoutListMarker* marker = Marker();
+ LayoutObject* line_box_parent = GetParentOfFirstLineBox(this);
LayoutBox* line_box_parent_block = nullptr;
if (!line_box_parent || !line_box_parent->IsBox()) {
back_to_original_baseline = true;
@@ -339,12 +345,12 @@ void LayoutListItem::AlignMarkerInBlockDirection() {
back_to_original_baseline = true;
}
- InlineBox* marker_inline_box = marker_->InlineBoxWrapper();
+ InlineBox* marker_inline_box = marker->InlineBoxWrapper();
RootInlineBox& marker_root = marker_inline_box->Root();
auto* line_box_parent_block_flow =
DynamicTo<LayoutBlockFlow>(line_box_parent_block);
if (line_box_parent_block && line_box_parent_block_flow) {
- // If marker_ and line_box_parent_block share a same RootInlineBox, no need
+ // If marker and line_box_parent_block share a same RootInlineBox, no need
// to align marker.
if (line_box_parent_block_flow->FirstRootBox() == &marker_root)
return;
@@ -355,7 +361,7 @@ void LayoutListItem::AlignMarkerInBlockDirection() {
offset = line_box_parent_block->FirstLineBoxBaseline();
if (back_to_original_baseline || offset == -1) {
- line_box_parent_block = marker_->ContainingBlock();
+ line_box_parent_block = marker->ContainingBlock();
offset = line_box_parent_block->FirstLineBoxBaseline();
}
@@ -369,11 +375,11 @@ void LayoutListItem::AlignMarkerInBlockDirection() {
// instead. BaselinePosition is workable when marker is an image.
// However, when marker is text, BaselinePosition contains lineheight
// information. So use marker_font_metrics.Ascent when marker is text.
- if (marker_->IsImage()) {
+ if (marker->IsImage()) {
offset -= marker_inline_box->BaselinePosition(marker_root.BaselineType());
} else {
const SimpleFontData* marker_font_data =
- marker_->Style(true)->GetFont().PrimaryFont();
+ marker->Style(true)->GetFont().PrimaryFont();
if (marker_font_data) {
const FontMetrics& marker_font_metrics =
marker_font_data->GetFontMetrics();
@@ -382,7 +388,7 @@ void LayoutListItem::AlignMarkerInBlockDirection() {
}
offset -= marker_inline_box->LogicalTop();
- for (LayoutBox* o = marker_->ParentBox(); o != this; o = o->ParentBox()) {
+ for (LayoutBox* o = marker->ParentBox(); o != this; o = o->ParentBox()) {
offset -= o->LogicalTop();
}
@@ -392,24 +398,25 @@ void LayoutListItem::AlignMarkerInBlockDirection() {
}
void LayoutListItem::UpdateOverflow() {
- if (!marker_ || !marker_->Parent() || !marker_->Parent()->IsBox() ||
- marker_->IsInside() || !marker_->InlineBoxWrapper())
+ LayoutListMarker* marker = Marker();
+ if (!marker || !marker->Parent() || !marker->Parent()->IsBox() ||
+ marker->IsInsideListMarker() || !marker->InlineBoxWrapper())
return;
if (need_block_direction_align_)
AlignMarkerInBlockDirection();
- LayoutUnit marker_old_logical_left = marker_->LogicalLeft();
+ LayoutUnit marker_old_logical_left = marker->LogicalLeft();
LayoutUnit block_offset;
LayoutUnit line_offset;
- for (LayoutBox* o = marker_->ParentBox(); o != this; o = o->ParentBox()) {
+ for (LayoutBox* o = marker->ParentBox(); o != this; o = o->ParentBox()) {
block_offset += o->LogicalTop();
line_offset += o->LogicalLeft();
}
bool adjust_overflow = false;
LayoutUnit marker_logical_left;
- InlineBox* marker_inline_box = marker_->InlineBoxWrapper();
+ InlineBox* marker_inline_box = marker->InlineBoxWrapper();
RootInlineBox& root = marker_inline_box->Root();
bool hit_self_painting_layer = false;
@@ -427,11 +434,11 @@ void LayoutListItem::UpdateOverflow() {
// FIXME: Need to account for relative positioning in the layout overflow.
if (StyleRef().IsLeftToRightDirection()) {
LayoutUnit marker_line_offset =
- std::min(marker_->LineOffset(),
- LogicalLeftOffsetForLine(marker_->LogicalTop(),
+ std::min(marker->LineOffset(),
+ LogicalLeftOffsetForLine(marker->LogicalTop(),
kDoNotIndentText, LayoutUnit()));
marker_logical_left = marker_line_offset - line_offset - PaddingStart() -
- BorderStart() + marker_->MarginStart();
+ BorderStart() + marker->MarginStart();
marker_inline_box->MoveInInlineDirection(marker_logical_left -
marker_old_logical_left);
@@ -468,11 +475,11 @@ void LayoutListItem::UpdateOverflow() {
}
} else {
LayoutUnit marker_line_offset =
- std::max(marker_->LineOffset(),
- LogicalRightOffsetForLine(marker_->LogicalTop(),
+ std::max(marker->LineOffset(),
+ LogicalRightOffsetForLine(marker->LogicalTop(),
kDoNotIndentText, LayoutUnit()));
marker_logical_left = marker_line_offset - line_offset + PaddingStart() +
- BorderStart() + marker_->MarginEnd();
+ BorderStart() + marker->MarginEnd();
marker_inline_box->MoveInInlineDirection(marker_logical_left -
marker_old_logical_left);
@@ -482,11 +489,11 @@ void LayoutListItem::UpdateOverflow() {
box->AddReplacedChildrenVisualOverflow(line_top, line_bottom);
LayoutRect new_logical_visual_overflow_rect =
box->LogicalVisualOverflowRect(line_top, line_bottom);
- if (marker_logical_left + marker_->LogicalWidth() >
+ if (marker_logical_left + marker->LogicalWidth() >
new_logical_visual_overflow_rect.MaxX() &&
!hit_self_painting_layer) {
new_logical_visual_overflow_rect.SetWidth(
- marker_logical_left + marker_->LogicalWidth() -
+ marker_logical_left + marker->LogicalWidth() -
new_logical_visual_overflow_rect.X());
if (box == root)
adjust_overflow = true;
@@ -498,10 +505,10 @@ void LayoutListItem::UpdateOverflow() {
hit_self_painting_layer = true;
LayoutRect new_logical_layout_overflow_rect =
box->LogicalLayoutOverflowRect(line_top, line_bottom);
- if (marker_logical_left + marker_->LogicalWidth() >
+ if (marker_logical_left + marker->LogicalWidth() >
new_logical_layout_overflow_rect.MaxX()) {
new_logical_layout_overflow_rect.SetWidth(
- marker_logical_left + marker_->LogicalWidth() -
+ marker_logical_left + marker->LogicalWidth() -
new_logical_layout_overflow_rect.X());
if (box == root)
adjust_overflow = true;
@@ -518,10 +525,10 @@ void LayoutListItem::UpdateOverflow() {
LayoutRect marker_rect(
LayoutPoint(marker_logical_left + line_offset,
block_offset + marker_inline_box->LogicalTop()),
- marker_->Size());
+ marker->Size());
if (!StyleRef().IsHorizontalWritingMode())
marker_rect = marker_rect.TransposedRect();
- LayoutBox* object = marker_;
+ LayoutBox* object = marker;
bool found_self_painting_layer = false;
do {
@@ -549,16 +556,16 @@ void LayoutListItem::Paint(const PaintInfo& paint_info) const {
}
const String& LayoutListItem::MarkerText() const {
- if (marker_)
- return marker_->GetText();
+ if (LayoutListMarker* marker = Marker())
+ return marker->GetText();
return g_null_atom.GetString();
}
void LayoutListItem::OrdinalValueChanged() {
- if (!marker_)
- return;
- marker_->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
- layout_invalidation_reason::kListValueChange);
+ if (LayoutListMarker* marker = Marker()) {
+ marker->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
+ layout_invalidation_reason::kListValueChange);
+ }
}
} // namespace blink