| 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 ae36c01f2a4b361f26bf908a82bfa302039e5e44..69727fce57533f84d4f6d3da062392f00fee360f 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/inspector/InspectorInstrumentation.h"
|
| #include "core/layout/LayoutObject.h"
|
| @@ -97,8 +98,7 @@ PseudoElement::PseudoElement(Element* parent, PseudoId pseudoId)
|
| }
|
|
|
| PassRefPtr<ComputedStyle> PseudoElement::customStyleForLayoutObject() {
|
| - return parentOrShadowHostElement()->layoutObject()->getCachedPseudoStyle(
|
| - m_pseudoId);
|
| + return parentOrShadowHostElement()->pseudoStyle(m_pseudoId);
|
| }
|
|
|
| void PseudoElement::dispose() {
|
| @@ -121,20 +121,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(document(), 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 {
|
| @@ -143,25 +146,67 @@ void PseudoElement::attachLayoutTree(const AttachContext& context) {
|
| }
|
| }
|
|
|
| +void PseudoElement::detachLayoutTree(const AttachContext& context) {
|
| + Element::detachLayoutTree(context);
|
| +}
|
| +
|
| bool PseudoElement::layoutObjectIsNeeded(const ComputedStyle& style) {
|
| return pseudoElementLayoutObjectIsNeeded(&style);
|
| }
|
|
|
| -void PseudoElement::didRecalcStyle() {
|
| - if (!layoutObject())
|
| - return;
|
| +static bool isGeneratedContentLike(LayoutObject* layoutObject) {
|
| + 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);
|
| + }
|
| + }
|
| +
|
| + DCHECK(foundGeneratedContent);
|
| }
|
| }
|
|
|
|
|