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 e1cbf151fe88f7bbdf108b79356b814a4212a9a5..e32818b8d8cccf937ca61a2b9280ec836068c47c 100644 |
--- a/third_party/WebKit/Source/core/dom/Element.cpp |
+++ b/third_party/WebKit/Source/core/dom/Element.cpp |
@@ -1574,8 +1574,13 @@ const AtomicString Element::imageSourceURL() const { |
} |
bool Element::layoutObjectIsNeeded(const ComputedStyle& style) { |
- return style.display() != EDisplay::None && |
- style.display() != EDisplay::Contents; |
+ if (style.display() == EDisplay::None) |
+ return false; |
+ |
+ if (style.display() == EDisplay::Contents) |
+ return isPseudoElement(); |
rune
2017/03/13 10:29:50
What layout object is needed and created for the :
emilio
2017/03/13 13:28:31
Whoops, this is leftover from the previous approac
|
+ |
+ return true; |
} |
LayoutObject* Element::createLayoutObject(const ComputedStyle& style) { |
@@ -2004,9 +2009,13 @@ StyleRecalcChange Element::recalcOwnStyle(StyleRecalcChange change, |
// https://codereview.chromium.org/30453002/ |
layoutObject->setStyleInternal(newStyle.get()); |
} |
- } else if (localChange != NoChange && |
- shouldStoreNonLayoutObjectComputedStyle(*newStyle)) { |
- storeNonLayoutObjectComputedStyle(newStyle); |
+ } else { |
+ if (localChange != NoChange) { |
+ if (shouldStoreNonLayoutObjectComputedStyle(*newStyle)) |
+ storeNonLayoutObjectComputedStyle(newStyle); |
+ else if (hasRareData()) |
+ elementRareData()->clearComputedStyle(); |
+ } |
} |
if (getStyleChangeType() >= SubtreeStyleChange) |
@@ -3181,18 +3190,24 @@ const ComputedStyle* Element::ensureComputedStyle( |
if (!pseudoElementSpecifier) |
return elementStyle; |
- if (ComputedStyle* pseudoElementStyle = |
+ if (ComputedStyle* cached = |
elementStyle->getCachedPseudoStyle(pseudoElementSpecifier)) |
- return pseudoElementStyle; |
+ return cached; |
rune
2017/03/13 10:29:50
This and the code below duplicates the code in Ele
emilio
2017/03/13 13:28:31
No, I can't. We use pseudoStyleForElement instead
|
+ |
+ const ComputedStyle* layoutParentStyle = elementStyle; |
+ if (hasDisplayContentsStyle()) { |
+ LayoutObject* parentLayoutObject = |
+ LayoutTreeBuilderTraversal::parentLayoutObject(*this); |
+ if (parentLayoutObject) |
+ layoutParentStyle = parentLayoutObject->style(); |
+ } |
- // TODO(ecobos): Passing two times elementStyle may be wrong, though we don't |
- // support display: contents elements' pseudo-elements yet, so this is not a |
- // problem for now. |
RefPtr<ComputedStyle> result = |
document().ensureStyleResolver().pseudoStyleForElement( |
- this, PseudoStyleRequest(pseudoElementSpecifier, |
- PseudoStyleRequest::ForComputedStyle), |
- elementStyle, elementStyle); |
+ this, |
+ PseudoStyleRequest(pseudoElementSpecifier, |
+ PseudoStyleRequest::ForComputedStyle), |
+ elementStyle, layoutParentStyle); |
DCHECK(result); |
return elementStyle->addCachedPseudoStyle(result.release()); |
} |
@@ -3276,7 +3291,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 |
@@ -3288,9 +3303,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 (!canHaveGeneratedPseudo(pseudoId) || |
+ !pseudoElementLayoutObjectIsNeeded(pseudoStyle(pseudoId))) |
elementRareData()->setPseudoElement(pseudoId, nullptr); |
} else if (pseudoId == PseudoIdFirstLetter && element && |
change >= UpdatePseudoElements && |
@@ -3327,6 +3341,48 @@ bool Element::updateFirstLetter(Element* element) { |
return false; |
} |
+ComputedStyle* Element::pseudoStyle(PseudoId pseudoId) const { |
+ ComputedStyle* style = mutableComputedStyle(); |
+ DCHECK(pseudoId < FirstInternalPseudoId); |
+ if (!style->hasPseudoStyle(pseudoId)) |
+ return nullptr; |
+ |
+ if (ComputedStyle* cached = style->getCachedPseudoStyle(pseudoId)) |
+ return cached; |
+ RefPtr<ComputedStyle> uncached = getUncachedPseudoStyle(pseudoId); |
+ if (uncached) |
+ return style->addCachedPseudoStyle(uncached.release()); |
+ return nullptr; |
+} |
+ |
+PassRefPtr<ComputedStyle> Element::getUncachedPseudoStyle( |
+ PseudoId pseudoId) const { |
+ if (pseudoId == PseudoIdBefore || pseudoId == PseudoIdAfter) { |
+ LayoutObject* parentLayoutObject = layoutObject(); |
+ if (!parentLayoutObject && hasDisplayContentsStyle()) { |
+ parentLayoutObject = |
+ LayoutTreeBuilderTraversal::parentLayoutObject(*this); |
+ } |
+ if (!parentLayoutObject) |
+ return nullptr; |
+ return document().ensureStyleResolver().pseudoStyleForElement( |
+ const_cast<Element*>(this), PseudoStyleRequest(pseudoId), |
+ computedStyle(), parentLayoutObject->style()); |
+ } |
+ if (!layoutObject()) |
+ return nullptr; |
+ return layoutObject()->getUncachedPseudoStyle(PseudoStyleRequest(pseudoId)); |
+} |
+ |
+// 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::canHaveGeneratedPseudo(PseudoId pseudoId) const { |
+ if (hasDisplayContentsStyle()) |
+ return pseudoId == PseudoIdBefore || pseudoId == PseudoIdAfter; |
+ return !!layoutObject(); |
+} |
+ |
void Element::createPseudoElementIfNeeded(PseudoId pseudoId) { |
if (isPseudoElement()) |
return; |