summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc57
1 files changed, 39 insertions, 18 deletions
diff --git a/chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc b/chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc
index 1fb038cc305..1317bbda431 100644
--- a/chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc
+++ b/chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc
@@ -4,8 +4,9 @@
#include "third_party/blink/renderer/core/html/list_item_ordinal.h"
-#include "base/numerics/clamped_math.h"
+#include "base/numerics/safe_conversions.h"
#include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h"
+#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/html/html_olist_element.h"
#include "third_party/blink/renderer/core/layout/layout_list_item.h"
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
@@ -74,7 +75,6 @@ ListItemOrdinal::NodeAndOrdinal ListItemOrdinal::NextListItem(
const Node* current = item ? item : list_node;
DCHECK(current);
- DCHECK(!current->GetDocument().ChildNeedsDistributionRecalc());
current = LayoutTreeBuilderTraversal::Next(*current, list_node);
while (current) {
@@ -102,7 +102,6 @@ ListItemOrdinal::NodeAndOrdinal ListItemOrdinal::PreviousListItem(
const Node* item) {
const Node* current = item;
DCHECK(current);
- DCHECK(!current->GetDocument().ChildNeedsDistributionRecalc());
for (current = LayoutTreeBuilderTraversal::Previous(*current, list_node);
current && current != list_node;
current = LayoutTreeBuilderTraversal::Previous(*current, list_node)) {
@@ -145,19 +144,27 @@ int ListItemOrdinal::CalcValue(const Node& item_node) const {
Node* list = EnclosingList(&item_node);
auto* o_list_element = DynamicTo<HTMLOListElement>(list);
- int value_step = 1;
- if (o_list_element && o_list_element->IsReversed())
- value_step = -1;
+ const bool is_reversed = o_list_element && o_list_element->IsReversed();
+ int value_step = is_reversed ? -1 : 1;
+ if (const auto* style = item_node.GetComputedStyle()) {
+ const auto directives =
+ style->GetCounterDirectives(AtomicString("list-item"));
+ if (directives.IsSet())
+ return directives.CombinedValue();
+ if (directives.IsIncrement())
+ value_step = directives.CombinedValue();
+ }
+ int64_t base_value = 0;
// FIXME: This recurses to a possible depth of the length of the list.
// That's not good -- we need to change this to an iterative algorithm.
- if (NodeAndOrdinal previous = PreviousListItem(list, &item_node))
- return base::ClampAdd(previous.ordinal->Value(*previous.node), value_step);
-
- if (o_list_element)
- return o_list_element->StartConsideringItemCount();
-
- return 1;
+ if (NodeAndOrdinal previous = PreviousListItem(list, &item_node)) {
+ base_value = previous.ordinal->Value(*previous.node);
+ } else if (o_list_element) {
+ base_value = o_list_element->StartConsideringItemCount();
+ base_value += (is_reversed ? 1 : -1);
+ }
+ return base::saturated_cast<int>(base_value + value_step);
}
int ListItemOrdinal::Value(const Node& item_node) const {
@@ -249,10 +256,8 @@ void ListItemOrdinal::InvalidateAllItemsForOrderedList(
// TODO(layout-dev): We should use layout tree traversal instead of flat tree
// traversal to invalidate ordinal number cache since lite items in unassigned
// slots don't have cached value. See http://crbug.com/844277 for details.
-void ListItemOrdinal::ItemInsertedOrRemoved(
- const LayoutObject* layout_list_item) {
- // If distribution recalc is needed, updateListMarkerNumber will be re-invoked
- // after distribution is calculated.
+void ListItemOrdinal::ItemUpdated(const LayoutObject* layout_list_item,
+ UpdateType type) {
const Node* item_node = layout_list_item->GetNode();
if (item_node->GetDocument().IsSlotAssignmentOrLegacyDistributionDirty())
return;
@@ -264,7 +269,8 @@ void ListItemOrdinal::ItemInsertedOrRemoved(
bool is_list_reversed = false;
if (auto* o_list_element = DynamicTo<HTMLOListElement>(list_node)) {
- o_list_element->ItemCountChanged();
+ if (type == kInsertedOrRemoved)
+ o_list_element->ItemCountChanged();
is_list_reversed = o_list_element->IsReversed();
}
@@ -276,7 +282,22 @@ void ListItemOrdinal::ItemInsertedOrRemoved(
if (list_node->NeedsReattachLayoutTree())
return;
+ if (type == kCounterStyle) {
+ ListItemOrdinal* ordinal = Get(*item_node);
+ DCHECK(ordinal);
+ ordinal->InvalidateSelf(*item_node);
+ }
InvalidateOrdinalsAfter(is_list_reversed, list_node, item_node);
}
+void ListItemOrdinal::ItemInsertedOrRemoved(
+ const LayoutObject* layout_list_item) {
+ ItemUpdated(layout_list_item, kInsertedOrRemoved);
+}
+
+void ListItemOrdinal::ItemCounterStyleUpdated(
+ const LayoutObject& layout_list_item) {
+ ItemUpdated(&layout_list_item, kCounterStyle);
+}
+
} // namespace blink