Index: third_party/WebKit/Source/core/dom/PseudoElement.cpp |
diff --git a/third_party/WebKit/Source/core/dom/PseudoElement.cpp b/third_party/WebKit/Source/core/dom/PseudoElement.cpp |
index 02b89a54b169f147c2a60c54cb20da313e7c778a..4d282aa87bb1ff0e59d3a6d94316b9c4ff661749 100644 |
--- a/third_party/WebKit/Source/core/dom/PseudoElement.cpp |
+++ b/third_party/WebKit/Source/core/dom/PseudoElement.cpp |
@@ -27,6 +27,7 @@ |
#include "core/dom/PseudoElement.h" |
#include "core/dom/FirstLetterPseudoElement.h" |
+#include "core/dom/NodeComputedStyle.h" |
#include "core/frame/UseCounter.h" |
#include "core/layout/LayoutObject.h" |
#include "core/layout/LayoutQuote.h" |
@@ -121,20 +122,23 @@ void PseudoElement::attachLayoutTree(const AttachContext& context) { |
Element::attachLayoutTree(context); |
- LayoutObject* layoutObject = this->layoutObject(); |
- if (!layoutObject) |
+ ComputedStyle* style = mutableComputedStyle(); |
+ if (!style || (style->styleType() != PseudoIdBefore && |
+ style->styleType() != PseudoIdAfter)) |
return; |
- ComputedStyle& style = layoutObject->mutableStyleRef(); |
- if (style.styleType() != PseudoIdBefore && style.styleType() != PseudoIdAfter) |
- return; |
- DCHECK(style.contentData()); |
+ DCHECK(style->contentData()); |
+ |
+ LayoutObject* parentLayoutObject = layoutObject(); |
+ if (!parentLayoutObject) |
+ parentLayoutObject = LayoutTreeBuilderTraversal::parentLayoutObject(*this); |
- for (const ContentData* content = style.contentData(); content; |
+ for (const ContentData* content = style->contentData(); content; |
content = content->next()) { |
- LayoutObject* child = content->createLayoutObject(*this, style); |
- if (layoutObject->isChildAllowed(child, style)) { |
- layoutObject->addChild(child); |
+ LayoutObject* child = content->createLayoutObject(*this, *style); |
+ if (parentLayoutObject->isChildAllowed(child, *style)) { |
+ parentLayoutObject->addChild(child); |
+ DCHECK(child->isPseudoElementGeneratedContentFor(*this)); |
if (child->isQuote()) |
toLayoutQuote(child)->attachQuote(); |
} else { |
@@ -147,21 +151,59 @@ bool PseudoElement::layoutObjectIsNeeded(const ComputedStyle& style) { |
return pseudoElementLayoutObjectIsNeeded(&style); |
} |
-void PseudoElement::didRecalcStyle() { |
- if (!layoutObject()) |
- return; |
+static bool isGeneratedContentLike(LayoutObject* layoutObject) { |
rune
2017/04/04 14:23:41
Why not call it isGeneratedContent?
emilio
2017/04/04 15:09:18
Sounds good to me, yeah.
|
+ if (!layoutObject->isAnonymous()) |
+ return false; |
+ return layoutObject->isText() || layoutObject->isQuote() || |
+ layoutObject->isImage(); |
+} |
+static void updateGeneratedContentStyleIn(LayoutObject* root, |
+ ComputedStyle* style) { |
+ for (LayoutObject* child = root; child; child = child->nextInPreOrder(root)) { |
+ if (isGeneratedContentLike(child)) |
+ child->setPseudoStyle(style); |
+ } |
+} |
+ |
+void PseudoElement::didRecalcStyle() { |
// The layoutObjects inside pseudo elements are anonymous so they don't get |
// notified of recalcStyle and must have the style propagated downward |
// manually similar to LayoutObject::propagateStyleToAnonymousChildren. |
- LayoutObject* layoutObject = this->layoutObject(); |
- for (LayoutObject* child = layoutObject->nextInPreOrder(layoutObject); child; |
- child = child->nextInPreOrder(layoutObject)) { |
- // We only manage the style for the generated content items. |
- if (!child->isText() && !child->isQuote() && !child->isImage()) |
- continue; |
- |
- child->setPseudoStyle(layoutObject->mutableStyle()); |
+ if (LayoutObject* layoutObject = this->layoutObject()) { |
+ updateGeneratedContentStyleIn(layoutObject, layoutObject->mutableStyle()); |
+ } else if (hasDisplayContentsStyle()) { |
+ DCHECK(m_pseudoId == PseudoIdBefore || m_pseudoId == PseudoIdAfter); |
+ |
+ LayoutObject* layoutParent = |
+ LayoutTreeBuilderTraversal::parentLayoutObject(*this); |
+ if (!layoutParent) |
+ return; |
+ |
+ const bool isBefore = m_pseudoId == PseudoIdBefore; |
+ ComputedStyle* style = mutableComputedStyle(); |
+ LayoutObject* child = isBefore ? layoutParent->slowFirstChild() |
+ : layoutParent->slowLastChild(); |
+ |
+ bool foundGeneratedContent = false; |
+ while (child) { |
+ bool isThisPseudoContent = |
+ child->isPseudoElementGeneratedContentFor(*this); |
+ if (isThisPseudoContent) |
+ foundGeneratedContent = true; |
+ else if (foundGeneratedContent) |
+ break; |
+ |
+ if (isThisPseudoContent) { |
+ updateGeneratedContentStyleIn(child, style); |
+ child = isBefore ? child->nextSibling() : child->previousSibling(); |
+ } else { |
+ child = isBefore ? child->nextInPreOrder(layoutParent) |
+ : child->previousInPreOrder(layoutParent); |
rune
2017/04/04 14:23:41
Why do you need to to walk descendants here?
In g
emilio
2017/04/04 15:09:18
The idea is to handle them, yeah. Right now I don'
|
+ } |
+ } |
+ |
+ DCHECK(foundGeneratedContent); |
} |
} |