Commit cb81b916 authored by rune@opera.com's avatar rune@opera.com

Use invalidation set for :empty pseudo changes.

Schedule an invalidation set for :empty on an element when the pseudo state
changes instead of a SubtreeStyleChange.

R=chrishtr@chromium.org,esprehn@chromium.org
BUG=412999

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

git-svn-id: svn://svn.chromium.org/blink/trunk@181805 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 9e34e499
Use descendant invalidation set for :empty pseudo class.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS getComputedStyle(empty, '').backgroundColor is green
PASS internals.updateStyleAndReturnAffectedElementCount() is 2
PASS getComputedStyle(empty, '').backgroundColor is transparent
PASS getComputedStyle(notEmpty, '').backgroundColor is transparent
PASS internals.updateStyleAndReturnAffectedElementCount() is 1
PASS getComputedStyle(notEmpty, '').backgroundColor is green
PASS successfullyParsed is true
TEST COMPLETE
Use descendant invalidation set for :empty pseudo class - sibling invalidation.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS getComputedStyle(emptySibling, '').backgroundColor is green
PASS internals.updateStyleAndReturnAffectedElementCount() is 7
PASS getComputedStyle(emptySibling, '').backgroundColor is transparent
PASS getComputedStyle(notEmptySibling, '').backgroundColor is transparent
PASS internals.updateStyleAndReturnAffectedElementCount() is 6
PASS getComputedStyle(notEmptySibling, '').backgroundColor is green
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<script src="../../../resources/js-test.js"></script>
<style>
:empty + div { background-color: green }
</style>
<div id="empty"></div>
<div id="emptySibling">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div id="notEmpty"><div id="child"></div></div>
<div id="notEmptySibling">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<script>
description("Use descendant invalidation set for :empty pseudo class - sibling invalidation.")
var transparent = "rgba(0, 0, 0, 0)";
var green = "rgb(0, 128, 0)";
shouldBe("getComputedStyle(emptySibling, '').backgroundColor", "green");
empty.offsetTop; // force recalc
empty.appendChild(document.createElement("div"));
if (window.internals)
shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "7");
shouldBe("getComputedStyle(emptySibling, '').backgroundColor", "transparent");
shouldBe("getComputedStyle(notEmptySibling, '').backgroundColor", "transparent");
notEmpty.offsetTop; // force recalc
notEmpty.removeChild(child);
if (window.internals)
shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "6");
shouldBe("getComputedStyle(notEmptySibling, '').backgroundColor", "green");
</script>
<!DOCTYPE html>
<script src="../../../resources/js-test.js"></script>
<style>
:empty { background-color: green }
#empty + div, #not-empty + div { color: pink }
</style>
<div id="empty"></div>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div id="notEmpty"><div id="child"></div></div>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<script>
description("Use descendant invalidation set for :empty pseudo class.")
var transparent = "rgba(0, 0, 0, 0)";
var green = "rgb(0, 128, 0)";
shouldBe("getComputedStyle(empty, '').backgroundColor", "green");
empty.offsetTop; // force recalc
empty.appendChild(document.createElement("div"));
if (window.internals)
shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "2");
shouldBe("getComputedStyle(empty, '').backgroundColor", "transparent");
shouldBe("getComputedStyle(notEmpty, '').backgroundColor", "transparent");
notEmpty.offsetTop; // force recalc
notEmpty.removeChild(child);
if (window.internals)
shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "1");
shouldBe("getComputedStyle(notEmpty, '').backgroundColor", "green");
</script>
...@@ -212,9 +212,15 @@ DescendantInvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSS ...@@ -212,9 +212,15 @@ DescendantInvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSS
if (selector.match() == CSSSelector::Id) if (selector.match() == CSSSelector::Id)
return &ensureIdInvalidationSet(selector.value()); return &ensureIdInvalidationSet(selector.value());
if (selector.match() == CSSSelector::PseudoClass) { if (selector.match() == CSSSelector::PseudoClass) {
CSSSelector::PseudoType pseudo = selector.pseudoType(); switch (selector.pseudoType()) {
if (pseudo == CSSSelector::PseudoHover || pseudo == CSSSelector::PseudoActive || pseudo == CSSSelector::PseudoFocus) case CSSSelector::PseudoEmpty:
return &ensurePseudoInvalidationSet(pseudo); case CSSSelector::PseudoHover:
case CSSSelector::PseudoActive:
case CSSSelector::PseudoFocus:
return &ensurePseudoInvalidationSet(selector.pseudoType());
default:
break;
}
} }
return 0; return 0;
} }
......
...@@ -1718,9 +1718,15 @@ void Element::checkForEmptyStyleChange() ...@@ -1718,9 +1718,15 @@ void Element::checkForEmptyStyleChange()
if (!style && !styleAffectedByEmpty()) if (!style && !styleAffectedByEmpty())
return; return;
if (styleChangeType() >= SubtreeStyleChange)
return;
if (!inActiveDocument())
return;
if (!document().styleResolver())
return;
if (!style || (styleAffectedByEmpty() && (!style->emptyState() || hasChildren()))) if (!style || (styleAffectedByEmpty() && (!style->emptyState() || hasChildren())))
setNeedsStyleRecalc(SubtreeStyleChange); document().styleResolver()->ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoEmpty, *this);
} }
void Element::childrenChanged(const ChildrenChange& change) void Element::childrenChanged(const ChildrenChange& change)
......
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