Commit a434069c authored by timloh@chromium.org's avatar timloh@chromium.org

Fix usage of pseudo style cache

This patch fixes our usage of the pseudo style cache so that we will
use a cached pseudo style when creating pseudo-elements if possible
and so that we cache pseudo styles even if they don't get a renderer.
We also move the logic for having styles with animations or transitions
be non-sharable from RenderStyle::isSharable to the StyleAdjuster, so
that animated pseudo-elements will have their parent's style correctly
marked as non-sharable.

As a result, a pseudo-element without a renderer (e.g. display:none
or content:none) to will correctly return its computed style to
getComputedStyle. This also fixes a regression where the pseudo style
cache can end up very large when its parent style is shared.

BUG=345653

Review URL: https://codereview.chromium.org/196143004

git-svn-id: svn://svn.chromium.org/blink/trunk@169619 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent e3c3ef65
......@@ -10,4 +10,4 @@ PASS div.offsetWidth is within 1 of 20
PASS div.offsetWidth is within 1 of 20
PASS div.offsetWidth is within 1 of 12
PASS div.offsetWidth is within 1 of 12
......@@ -4,29 +4,17 @@
<style>
@-webkit-keyframes example {
from {
width: 50px;
height: 50px;
}
to {
width: 10px;
height: 10px;
}
from { width: 50px; height: 50px; }
to { width: 10px; height: 10px; }
}
@keyframes example {
from {
width: 50px;
height: 50px;
}
to {
width: 10px;
height: 10px;
}
from { width: 50px; height: 50px; }
to { width: 10px; height: 10px; }
}
#after:after,
#before:before {
.after:after,
.before:before {
content: "";
display: block;
position: relative;
......@@ -38,8 +26,8 @@
animation: example 2s;
}
#before,
#after {
.before,
.after {
display: inline-block;
border: 1px solid black;
background: red;
......@@ -47,8 +35,12 @@
</style>
<div id="before"></div>
<div id="after"></div>
<div class="before"></div>
<div class="before" id="before"></div>
<div class="before"></div>
<div class="after"></div>
<div class="after" id="after"></div>
<div class="after"></div>
<script>
description('Animations on :before and :after pseudo elements should run when applied before onload.');
......
<!DOCTYPE html>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
#element:after { display: none; color: green; }
</style>
<div id="element"></div>
<script>
test(function() {
var computedStyle = getComputedStyle(document.getElementById('element'), ":after");
assert_equals(computedStyle.color, 'rgb(0, 128, 0)');
assert_equals(computedStyle.display, 'none');
}, 'getComputedStyle works on pseudo-element without renderer');
</script>
......@@ -280,8 +280,8 @@ void StyleAdjuster::adjustRenderStyle(RenderStyle* style, RenderStyle* parentSty
if (style->hasAppearance())
RenderTheme::theme().adjustStyle(style, e, m_cachedUAStyle);
// If we have first-letter pseudo style, do not share this style.
if (style->hasPseudoStyle(FIRST_LETTER))
// If we have first-letter pseudo style, transitions, or animations, do not share this style.
if (style->hasPseudoStyle(FIRST_LETTER) || style->transitions() || style->animations())
style->setUnique();
// FIXME: when dropping the -webkit prefix on transform-style, we should also have opacity < 1 cause flattening.
......
......@@ -834,16 +834,22 @@ PassRefPtr<PseudoElement> StyleResolver::createPseudoElementIfNeeded(Element& pa
return nullptr;
RenderStyle* parentStyle = parentRenderer->style();
if (RenderStyle* cachedStyle = parentStyle->getCachedPseudoStyle(pseudoId)) {
if (!pseudoElementRendererIsNeeded(cachedStyle))
return nullptr;
return PseudoElement::create(&parent, pseudoId);
}
StyleResolverState state(document(), &parent, parentStyle);
if (!pseudoStyleForElementInternal(parent, pseudoId, parentStyle, state))
return nullptr;
RefPtr<RenderStyle> style = state.takeStyle();
ASSERT(style);
parentStyle->addCachedPseudoStyle(style);
if (!pseudoElementRendererIsNeeded(style.get()))
return nullptr;
parentStyle->addCachedPseudoStyle(style.release());
RefPtr<PseudoElement> pseudo = PseudoElement::create(&parent, pseudoId);
setAnimationUpdateIfNeeded(state, *pseudo);
......
......@@ -1849,8 +1849,6 @@ inline bool RenderStyle::isSharable() const
return false;
if (hasUniquePseudoStyle())
return false;
if (transitions() || animations())
return false;
return true;
}
......
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