Index: third_party/WebKit/Source/core/dom/Element.cpp |
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp |
index 54669b40f5a9bb14fca0be788e54c62ba68c47dd..67b124ce7d2982aecb1fb8e44c307ac743d774db 100644 |
--- a/third_party/WebKit/Source/core/dom/Element.cpp |
+++ b/third_party/WebKit/Source/core/dom/Element.cpp |
@@ -3261,7 +3261,7 @@ void Element::updatePseudoElement(PseudoId pseudoId, StyleRecalcChange change) { |
// Need to clear the cached style if the PseudoElement wants a recalc so it |
// computes a new style. |
if (element->needsStyleRecalc()) |
- layoutObject()->mutableStyle()->removeCachedPseudoStyle(pseudoId); |
+ mutableComputedStyle()->removeCachedPseudoStyle(pseudoId); |
// PseudoElement styles hang off their parent element's style so if we |
// needed a style recalc we should Force one on the pseudo. FIXME: We |
@@ -3273,9 +3273,8 @@ void Element::updatePseudoElement(PseudoId pseudoId, StyleRecalcChange change) { |
// continuously create and destroy PseudoElements when |
// LayoutObject::isChildAllowed on our parent returns false for the |
// PseudoElement's layoutObject for each style recalc. |
- if (!layoutObject() || |
- !pseudoElementLayoutObjectIsNeeded( |
- layoutObject()->getCachedPseudoStyle(pseudoId))) |
+ if (!layoutObject() || !pseudoElementLayoutObjectIsNeeded( |
+ pseudoStyle(PseudoStyleRequest(pseudoId)))) |
elementRareData()->setPseudoElement(pseudoId, nullptr); |
} else if (pseudoId == PseudoIdFirstLetter && element && |
change >= UpdatePseudoElements && |
@@ -3344,6 +3343,64 @@ LayoutObject* Element::pseudoElementLayoutObject(PseudoId pseudoId) const { |
return nullptr; |
} |
+ComputedStyle* Element::pseudoStyle(const PseudoStyleRequest& request, |
+ const ComputedStyle* parentStyle) { |
+ ComputedStyle* style = mutableComputedStyle(); |
+ |
+ if (!style || (request.pseudoId < FirstInternalPseudoId && |
+ !style->hasPseudoStyle(request.pseudoId))) { |
+ return nullptr; |
+ } |
+ |
+ if (ComputedStyle* cached = style->getCachedPseudoStyle(request.pseudoId)) |
+ return cached; |
+ |
+ RefPtr<ComputedStyle> result = getUncachedPseudoStyle(request, parentStyle); |
+ if (result) |
+ return style->addCachedPseudoStyle(result.release()); |
+ return nullptr; |
+} |
+ |
+PassRefPtr<ComputedStyle> Element::getUncachedPseudoStyle( |
+ const PseudoStyleRequest& request, |
+ const ComputedStyle* parentStyle) { |
+ const ComputedStyle* style = computedStyle(); |
+ const bool isBeforeOrAfter = |
+ request.pseudoId == PseudoIdBefore || request.pseudoId == PseudoIdAfter; |
+ |
+ DCHECK(style); |
+ DCHECK(!parentStyle || !isBeforeOrAfter); |
+ |
+ if (isBeforeOrAfter) { |
+ LayoutObject* parentLayoutObject = layoutObject(); |
+ if (!parentLayoutObject && hasDisplayContentsStyle()) { |
+ parentLayoutObject = |
+ LayoutTreeBuilderTraversal::parentLayoutObject(*this); |
+ } |
+ if (!parentLayoutObject) |
+ return nullptr; |
+ return document().ensureStyleResolver().pseudoStyleForElement( |
+ this, request, style, parentLayoutObject->style()); |
+ } |
+ |
+ if (!layoutObject()) |
+ return nullptr; |
+ |
+ if (!parentStyle) |
+ parentStyle = style; |
+ |
+ if (request.pseudoId == PseudoIdFirstLineInherited) { |
+ RefPtr<ComputedStyle> result = |
+ document().ensureStyleResolver().styleForElement( |
+ this, parentStyle, parentStyle, DisallowStyleSharing); |
+ result->setStyleType(PseudoIdFirstLineInherited); |
+ return result.release(); |
+ } |
+ |
+ return document().ensureStyleResolver().pseudoStyleForElement( |
+ this, request, parentStyle, parentStyle); |
+} |
+ |
bool Element::matches(const AtomicString& selectors, |
ExceptionState& exceptionState) { |
SelectorQuery* selectorQuery = document().selectorQueryCache().add( |