Commit 2d21d004 authored by Rune Lillesveen's avatar Rune Lillesveen Committed by Commit Bot

[Squad] Make pseudo element creation not rely on layout tree.

- Base layout parent computed style on traversing the DOM instead of the
  layout tree.
- Moved top layer check for ::backdrop to CanGeneratePseudoElement().
- Moved CanHaveGeneratedChildren() to layout tree building. This means
  we may generate pseudo elements which may not generate boxes for their
  pseudo elements, but the boxes will still not be created.

First-letter is still relying on layout objects. Will address that
later.

Bug: 836126
Change-Id: I4f283a09db597bc44d1b32d1007b4aa65e83f2e0
Reviewed-on: https://chromium-review.googlesource.com/1092692Reviewed-by: default avatarAnders Ruud <andruud@chromium.org>
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565668}
parent f5e25550
...@@ -86,7 +86,6 @@ ...@@ -86,7 +86,6 @@
#include "third_party/blink/renderer/core/html/html_iframe_element.h" #include "third_party/blink/renderer/core/html/html_iframe_element.h"
#include "third_party/blink/renderer/core/html/html_slot_element.h" #include "third_party/blink/renderer/core/html/html_slot_element.h"
#include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/layout/generated_children.h"
#include "third_party/blink/renderer/core/media_type_names.h" #include "third_party/blink/renderer/core/media_type_names.h"
#include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/style/style_inherited_variables.h" #include "third_party/blink/renderer/core/style/style_inherited_variables.h"
...@@ -810,16 +809,6 @@ PseudoElement* StyleResolver::CreatePseudoElementIfNeeded(Element& parent, ...@@ -810,16 +809,6 @@ PseudoElement* StyleResolver::CreatePseudoElementIfNeeded(Element& parent,
if (!parent.CanGeneratePseudoElement(pseudo_id)) if (!parent.CanGeneratePseudoElement(pseudo_id))
return nullptr; return nullptr;
LayoutObject* parent_layout_object = parent.GetLayoutObject();
if (!parent_layout_object) {
DCHECK(parent.HasDisplayContentsStyle());
parent_layout_object =
LayoutTreeBuilderTraversal::ParentLayoutObject(parent);
}
if (!parent_layout_object)
return nullptr;
ComputedStyle* parent_style = parent.MutableComputedStyle(); ComputedStyle* parent_style = parent.MutableComputedStyle();
DCHECK(parent_style); DCHECK(parent_style);
...@@ -830,22 +819,11 @@ PseudoElement* StyleResolver::CreatePseudoElementIfNeeded(Element& parent, ...@@ -830,22 +819,11 @@ PseudoElement* StyleResolver::CreatePseudoElementIfNeeded(Element& parent,
return nullptr; return nullptr;
} }
if (pseudo_id == kPseudoIdBackdrop && !parent.IsInTopLayer())
return nullptr;
if (pseudo_id == kPseudoIdFirstLetter && if (pseudo_id == kPseudoIdFirstLetter &&
(parent.IsSVGElement() || (parent.IsSVGElement() ||
!FirstLetterPseudoElement::FirstLetterTextLayoutObject(parent))) !FirstLetterPseudoElement::FirstLetterTextLayoutObject(parent)))
return nullptr; return nullptr;
// The backdrop pseudo element generates a new stacking context and its
// layout object does not become a child of |parentLayoutObject|. The
// exemption is needed so that replaced content also gets a backdrop.
if (pseudo_id != kPseudoIdBackdrop &&
!CanHaveGeneratedChildren(*parent_layout_object)) {
return nullptr;
}
if (ComputedStyle* cached_style = if (ComputedStyle* cached_style =
parent_style->GetCachedPseudoStyle(pseudo_id)) { parent_style->GetCachedPseudoStyle(pseudo_id)) {
if (!PseudoElementLayoutObjectIsNeeded(cached_style)) if (!PseudoElementLayoutObjectIsNeeded(cached_style))
...@@ -853,8 +831,16 @@ PseudoElement* StyleResolver::CreatePseudoElementIfNeeded(Element& parent, ...@@ -853,8 +831,16 @@ PseudoElement* StyleResolver::CreatePseudoElementIfNeeded(Element& parent,
return PseudoElement::Create(&parent, pseudo_id); return PseudoElement::Create(&parent, pseudo_id);
} }
const ComputedStyle* layout_parent_style = parent_style;
if (parent.HasDisplayContentsStyle()) {
ContainerNode* layout_parent =
LayoutTreeBuilderTraversal::LayoutParent(parent);
DCHECK(layout_parent);
layout_parent_style = layout_parent->GetComputedStyle();
}
StyleResolverState state(GetDocument(), &parent, parent_style, StyleResolverState state(GetDocument(), &parent, parent_style,
parent_layout_object->Style()); layout_parent_style);
if (!PseudoStyleForElementInternal(parent, pseudo_id, parent_style, state)) if (!PseudoStyleForElementInternal(parent, pseudo_id, parent_style, state))
return nullptr; return nullptr;
scoped_refptr<ComputedStyle> style = state.TakeStyle(); scoped_refptr<ComputedStyle> style = state.TakeStyle();
......
...@@ -3990,13 +3990,22 @@ scoped_refptr<ComputedStyle> Element::GetUncachedPseudoStyle( ...@@ -3990,13 +3990,22 @@ scoped_refptr<ComputedStyle> Element::GetUncachedPseudoStyle(
return GetDocument().EnsureStyleResolver().PseudoStyleForElement( return GetDocument().EnsureStyleResolver().PseudoStyleForElement(
this, request, parent_style, parent_style); this, request, parent_style, parent_style);
} }
// For display: contents elements, we still need to generate ::before and
// ::after, but the rest of the pseudo-elements should only be used for elements
// with an actual layout object.
bool Element::CanGeneratePseudoElement(PseudoId pseudo_id) const { bool Element::CanGeneratePseudoElement(PseudoId pseudo_id) const {
if (HasDisplayContentsStyle()) if (pseudo_id == kPseudoIdBackdrop && !IsInTopLayer())
return pseudo_id == kPseudoIdBefore || pseudo_id == kPseudoIdAfter; return false;
return !!GetLayoutObject(); if (const ComputedStyle* style = GetComputedStyle()) {
if (style->Display() == EDisplay::kNone)
return false;
if (style->Display() == EDisplay::kContents) {
// For display: contents elements, we still need to generate ::before and
// ::after, but the rest of the pseudo-elements should only be used for
// elements with an actual layout object.
return pseudo_id == kPseudoIdBefore || pseudo_id == kPseudoIdAfter;
}
return true;
}
return false;
} }
bool Element::MayTriggerVirtualKeyboard() const { bool Element::MayTriggerVirtualKeyboard() const {
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "third_party/blink/renderer/core/dom/v0_insertion_point.h" #include "third_party/blink/renderer/core/dom/v0_insertion_point.h"
#include "third_party/blink/renderer/core/dom/whitespace_attacher.h" #include "third_party/blink/renderer/core/dom/whitespace_attacher.h"
#include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/layout/generated_children.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h" #include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_text.h" #include "third_party/blink/renderer/core/layout/layout_text.h"
...@@ -122,6 +123,10 @@ bool LayoutTreeBuilderForElement::ShouldCreateLayoutObject() const { ...@@ -122,6 +123,10 @@ bool LayoutTreeBuilderForElement::ShouldCreateLayoutObject() const {
return false; return false;
if (!parent_layout_object->CanHaveChildren()) if (!parent_layout_object->CanHaveChildren())
return false; return false;
if (node_->IsPseudoElement() &&
!CanHaveGeneratedChildren(*parent_layout_object)) {
return false;
}
return node_->LayoutObjectIsNeeded(Style()); return node_->LayoutObjectIsNeeded(Style());
} }
......
...@@ -148,9 +148,9 @@ void PseudoElement::AttachLayoutTree(AttachContext& context) { ...@@ -148,9 +148,9 @@ void PseudoElement::AttachLayoutTree(AttachContext& context) {
if (!layout_object) if (!layout_object)
return; return;
// This is to ensure that bypassing the canHaveGeneratedChildren check in // This is to ensure that bypassing the CanHaveGeneratedChildren() check in
// StyleResolver::createPseudoElementIfNeeded does not result in the // LayoutTreeBuilderForElement::ShouldCreateLayoutObject() does not result in
// backdrop pseudo element's layout object becoming the child of a layout // the backdrop pseudo element's layout object becoming the child of a layout
// object that doesn't allow children. // object that doesn't allow children.
DCHECK(layout_object->Parent()); DCHECK(layout_object->Parent());
DCHECK(CanHaveGeneratedChildren(*layout_object->Parent())); DCHECK(CanHaveGeneratedChildren(*layout_object->Parent()));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment