blob: 3969e5137af165d8bd645d917b9bd8d870dfd3d6 [file] [log] [blame]
// Copyright 2017 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/layout/ng/list/layout_ng_list_item.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/list_marker.h"
namespace blink {
LayoutNGListItem::LayoutNGListItem(Element* element)
: LayoutNGBlockFlow(element) {
SetInline(false);
SetConsumesSubtreeChangeNotification();
RegisterSubtreeChangeListenerOnDescendants(true);
View()->AddLayoutListItem();
}
void LayoutNGListItem::WillBeDestroyed() {
NOT_DESTROYED();
if (View())
View()->RemoveLayoutListItem();
LayoutNGBlockFlow::WillBeDestroyed();
}
bool LayoutNGListItem::IsOfType(LayoutObjectType type) const {
return type == kLayoutObjectNGListItem || LayoutNGBlockFlow::IsOfType(type);
}
void LayoutNGListItem::InsertedIntoTree() {
LayoutNGBlockFlow::InsertedIntoTree();
ListItemOrdinal::ItemInsertedOrRemoved(this);
}
void LayoutNGListItem::WillBeRemovedFromTree() {
LayoutNGBlockFlow::WillBeRemovedFromTree();
ListItemOrdinal::ItemInsertedOrRemoved(this);
}
void LayoutNGListItem::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
LayoutNGBlockFlow::StyleDidChange(diff, old_style);
LayoutObject* marker = Marker();
ListMarker* list_marker = ListMarker::Get(marker);
if (!list_marker)
return;
list_marker->UpdateMarkerContentIfNeeded(*marker);
if (old_style) {
const ListStyleTypeData* old_list_style_type =
old_style->GetListStyleType();
const ListStyleTypeData* new_list_style_type =
StyleRef().GetListStyleType();
if (old_list_style_type != new_list_style_type &&
(!old_list_style_type || !new_list_style_type ||
*old_list_style_type != *new_list_style_type))
list_marker->ListStyleTypeChanged(*marker);
}
}
void LayoutNGListItem::UpdateCounterStyle() {
if (!RuntimeEnabledFeatures::CSSAtRuleCounterStyleEnabled())
return;
if (!StyleRef().GetListStyleType() ||
StyleRef().GetListStyleType()->IsCounterStyleReferenceValid(
GetDocument())) {
return;
}
LayoutObject* marker = Marker();
ListMarker* list_marker = ListMarker::Get(marker);
if (!list_marker)
return;
list_marker->CounterStyleChanged(*marker);
}
void LayoutNGListItem::OrdinalValueChanged() {
LayoutObject* marker = Marker();
if (ListMarker* list_marker = ListMarker::Get(marker))
list_marker->OrdinalValueChanged(*marker);
}
void LayoutNGListItem::SubtreeDidChange() {
LayoutObject* marker = Marker();
ListMarker* list_marker = ListMarker::Get(marker);
if (!list_marker)
return;
// Make sure an outside marker is a direct child of the list item (not nested
// inside an anonymous box), and that a marker originated by a ::before or
// ::after precedes the generated contents.
if ((marker->IsLayoutNGOutsideListMarker() && marker->Parent() != this) ||
(IsPseudoElement() && marker != FirstChild())) {
marker->Remove();
AddChild(marker, FirstChild());
}
list_marker->UpdateMarkerContentIfNeeded(*marker);
}
void LayoutNGListItem::WillCollectInlines() {
UpdateMarkerTextIfNeeded();
}
void LayoutNGListItem::UpdateMarkerTextIfNeeded() {
LayoutObject* marker = Marker();
if (ListMarker* list_marker = ListMarker::Get(marker))
list_marker->UpdateMarkerTextIfNeeded(*marker);
}
int LayoutNGListItem::Value() const {
DCHECK(GetNode());
return ordinal_.Value(*GetNode());
}
const LayoutObject* LayoutNGListItem::FindSymbolMarkerLayoutText(
const LayoutObject* object) {
if (!object)
return nullptr;
if (const ListMarker* list_marker = ListMarker::Get(object))
return list_marker->SymbolMarkerLayoutText(*object);
if (object->IsLayoutNGListItem())
return FindSymbolMarkerLayoutText(To<LayoutNGListItem>(object)->Marker());
if (object->IsAnonymousBlock())
return FindSymbolMarkerLayoutText(object->Parent());
return nullptr;
}
} // namespace blink