diff options
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.cc | 45 |
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); |