summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc45
1 files changed, 35 insertions, 10 deletions
diff --git a/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc b/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc
index 38c9b9e9085..a1e641f23ef 100644
--- a/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc
+++ b/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc
@@ -101,7 +101,7 @@ LayoutText* FirstLetterPseudoElement::FirstLetterTextLayoutObject(
LayoutObject* parent_layout_object = nullptr;
// If we are looking at a first letter element then we need to find the
- // first letter text layoutObject from the parent node, and not ourselves.
+ // first letter text LayoutObject from the parent node, and not ourselves.
if (element.IsFirstLetterPseudoElement()) {
parent_layout_object =
element.ParentOrShadowHostElement()->GetLayoutObject();
@@ -147,9 +147,16 @@ LayoutText* FirstLetterPseudoElement::FirstLetterTextLayoutObject(
first_letter_text_layout_object->NextSibling();
} else if (first_letter_text_layout_object->IsListMarker() ||
first_letter_text_layout_object == marker) {
- first_letter_text_layout_object =
- first_letter_text_layout_object->NextInPreOrderAfterChildren(
- parent_layout_object);
+ // The list item marker may have out-of-flow siblings inside an anonymous
+ // block. Skip them to make sure we leave the anonymous block before
+ // continuing looking for the first letter text.
+ do {
+ first_letter_text_layout_object =
+ first_letter_text_layout_object->NextInPreOrderAfterChildren(
+ parent_layout_object);
+ } while (
+ first_letter_text_layout_object &&
+ first_letter_text_layout_object->IsFloatingOrOutOfFlowPositioned());
} else if (first_letter_text_layout_object
->IsFloatingOrOutOfFlowPositioned()) {
if (first_letter_text_layout_object->Style()->StyleType() ==
@@ -261,11 +268,29 @@ void FirstLetterPseudoElement::ClearRemainingTextLayoutObject() {
void FirstLetterPseudoElement::AttachLayoutTree(AttachContext& context) {
LayoutText* first_letter_text =
FirstLetterPseudoElement::FirstLetterTextLayoutObject(*this);
- PseudoElement::AttachLayoutTree(context);
- AttachFirstLetterTextLayoutObjects(first_letter_text);
+ // The FirstLetterPseudoElement should have been removed in
+ // Element::UpdateFirstLetterPseudoElement(). However if there existed a first
+ // letter before updating it, the layout tree will be different after
+ // DetachLayoutTree() called right before this method.
+ // If there is a bug in FirstLetterTextLayoutObject(), we might end up with
+ // null here. DCHECKing here, but handling the null pointer below to avoid
+ // crashes.
+ DCHECK(first_letter_text);
+
+ AttachContext first_letter_context(context);
+ first_letter_context.next_sibling = first_letter_text;
+ first_letter_context.next_sibling_valid = true;
+ if (first_letter_text) {
+ first_letter_context.parent = first_letter_text->Parent();
+ if (first_letter_context.parent->ForceLegacyLayout())
+ first_letter_context.force_legacy_layout = true;
+ }
+ PseudoElement::AttachLayoutTree(first_letter_context);
+ if (first_letter_text)
+ AttachFirstLetterTextLayoutObjects(first_letter_text);
}
-void FirstLetterPseudoElement::DetachLayoutTree(const AttachContext& context) {
+void FirstLetterPseudoElement::DetachLayoutTree(bool performing_reattach) {
if (remaining_text_layout_object_) {
if (remaining_text_layout_object_->GetNode() && GetDocument().IsActive()) {
auto* text_node = To<Text>(remaining_text_layout_object_->GetNode());
@@ -277,7 +302,7 @@ void FirstLetterPseudoElement::DetachLayoutTree(const AttachContext& context) {
}
remaining_text_layout_object_ = nullptr;
- PseudoElement::DetachLayoutTree(context);
+ PseudoElement::DetachLayoutTree(performing_reattach);
}
scoped_refptr<ComputedStyle>
@@ -326,7 +351,7 @@ void FirstLetterPseudoElement::AttachFirstLetterTextLayoutObjects(LayoutText* fi
remaining_text->SetFirstLetterPseudoElement(this);
remaining_text->SetIsRemainingTextLayoutObject(true);
- remaining_text->SetStyle(first_letter_text->MutableStyle());
+ remaining_text->SetStyle(first_letter_text->Style());
if (remaining_text->GetNode())
remaining_text->GetNode()->SetLayoutObject(remaining_text);
@@ -337,7 +362,7 @@ void FirstLetterPseudoElement::AttachFirstLetterTextLayoutObjects(LayoutText* fi
GetLayoutObject()->Parent()->AddChild(remaining_text, next_sibling);
// Construct text fragment for the first letter.
- ComputedStyle* const letter_style = MutableComputedStyle();
+ const ComputedStyle* const letter_style = GetComputedStyle();
LayoutTextFragment* letter = LayoutTextFragment::CreateAnonymous(
*this, old_text.Impl(), 0, length, legacy_layout);
letter->SetFirstLetterPseudoElement(this);