summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.cc
blob: a7b13fbcd69f7ecf257a8198b1f0be6952fa692f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// 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_marker.h"

#include "third_party/blink/renderer/core/layout/layout_text.h"
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"

namespace blink {

LayoutNGListMarker::LayoutNGListMarker(Element* element)
    : LayoutNGMixin<LayoutBlockFlow>(element) {}

LayoutNGListMarker* LayoutNGListMarker::CreateAnonymous(Document* document) {
  LayoutNGListMarker* object = new LayoutNGListMarker(nullptr);
  object->SetDocumentForAnonymous(document);
  return object;
}

bool LayoutNGListMarker::IsOfType(LayoutObjectType type) const {
  return type == kLayoutObjectNGListMarker ||
         LayoutNGMixin<LayoutBlockFlow>::IsOfType(type);
}

bool LayoutNGListMarker::IsListMarkerWrapperForBlockContent(
    const LayoutObject& object) {
  const auto* block_flow = DynamicTo<LayoutBlockFlow>(object);
  if (!object.IsAnonymous() || !block_flow)
    return false;
  if (const LayoutObject* child = block_flow->FirstChild()) {
    return child->IsLayoutNGListMarker() &&
           // The anonymous box should not have other children.
           // e.g., <li>text<div>block</div></li>
           // In this case, inline layout can handle the list marker.
           !child->NextSibling();
  }
  return false;
}

// The LayoutNGListItem this marker belongs to.
LayoutNGListItem* LayoutNGListMarker::ListItem() const {
  for (LayoutObject* parent = Parent(); parent; parent = parent->Parent()) {
    if (parent->IsLayoutNGListItem()) {
      DCHECK(ToLayoutNGListItem(parent)->Marker() == this);
      return ToLayoutNGListItem(parent);
    }
    // These DCHECKs are not critical but to ensure we cover all cases we know.
    DCHECK(parent->IsAnonymous());
    DCHECK(parent->IsLayoutBlockFlow() || parent->IsLayoutFlowThread());
  }
  return nullptr;
}

void LayoutNGListMarker::WillCollectInlines() {
  if (LayoutNGListItem* list_item = ListItem())
    list_item->UpdateMarkerTextIfNeeded();
}

bool LayoutNGListMarker::IsContentImage() const {
  return ListItem()->IsMarkerImage();
}

LayoutObject* LayoutNGListMarker::SymbolMarkerLayoutText() const {
  return ListItem()->SymbolMarkerLayoutText();
}

String LayoutNGListMarker::TextAlternative() const {
  // Compute from the list item, in the logical order even in RTL, reflecting
  // speech order.
  if (LayoutNGListItem* list_item = ListItem())
    return list_item->MarkerTextWithSuffix();
  return g_empty_string;
}

bool LayoutNGListMarker::NeedsOccupyWholeLine() const {
  if (!GetDocument().InQuirksMode())
    return false;

  LayoutObject* next_sibling = NextSibling();
  if (next_sibling && next_sibling->GetNode() &&
      (IsHTMLUListElement(*next_sibling->GetNode()) ||
       IsHTMLOListElement(*next_sibling->GetNode())))
    return true;

  return false;
}

}  // namespace blink