Diff
Modified: trunk/LayoutTests/ChangeLog (202226 => 202227)
--- trunk/LayoutTests/ChangeLog 2016-06-20 07:07:04 UTC (rev 202226)
+++ trunk/LayoutTests/ChangeLog 2016-06-20 08:52:10 UTC (rev 202227)
@@ -1,3 +1,14 @@
+2016-06-19 Antti Koivisto <[email protected]>
+
+ Updating class name of a shadow host does not update the style applied by :host()
+ https://bugs.webkit.org/show_bug.cgi?id=158900
+ <rdar://problem/26883707>
+
+ Reviewed by Simon Fraser.
+
+ * fast/shadow-dom/shadow-host-style-update-expected.html: Added.
+ * fast/shadow-dom/shadow-host-style-update.html: Added.
+
2016-06-19 Alexey Proskuryakov <[email protected]>
Test expectation gardening.
Added: trunk/LayoutTests/fast/shadow-dom/shadow-host-style-update-expected.html (0 => 202227)
--- trunk/LayoutTests/fast/shadow-dom/shadow-host-style-update-expected.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/shadow-host-style-update-expected.html 2016-06-20 08:52:10 UTC (rev 202227)
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+<body>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <div style="width: 100px; height: 100px; background: green;"></div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/shadow-dom/shadow-host-style-update.html (0 => 202227)
--- trunk/LayoutTests/fast/shadow-dom/shadow-host-style-update.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/shadow-host-style-update.html 2016-06-20 08:52:10 UTC (rev 202227)
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.test {
+ width: 100px;
+ height: 25px;
+ background: red;
+}
+</style>
+</head>
+<body>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host1" class="test"></div>
+<div id="host2" class="test"></div>
+<div id="host3" class="test"></div>
+<div id="host4" class="test" attr="red"></div>
+<script>
+
+var host1 = document.getElementById('host1');
+host1.attachShadow({mode: 'closed'}).innerHTML = `
+ <style>
+ :host(.green) {
+ background: green !important;
+ }
+ </style>
+`;
+
+getComputedStyle(host1).backgroundColor;
+host1.classList.toggle('green');
+
+var host2 = document.getElementById('host2');
+host2.attachShadow({mode: 'closed'}).innerHTML = `
+ <style>
+ :host(#greenID) {
+ background: green !important;
+ }
+ </style>
+`;
+
+getComputedStyle(host2).backgroundColor;
+host2.id = 'greenID';
+
+var host3 = document.getElementById('host3');
+host3.attachShadow({mode: 'closed'}).innerHTML = `
+ <style>
+ :host([greenAttr]) {
+ background: green !important;
+ }
+ </style>
+`;
+
+getComputedStyle(host3).backgroundColor;
+host3.setAttribute('greenAttr', '');
+
+var host4 = document.getElementById('host4');
+host4.attachShadow({mode: 'closed'}).innerHTML = `
+ <style>
+ :host([attr=green]) {
+ background: green !important;
+ }
+ </style>
+`;
+
+getComputedStyle(host4).backgroundColor;
+host4.setAttribute('attr', 'green');
+
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (202226 => 202227)
--- trunk/Source/WebCore/ChangeLog 2016-06-20 07:07:04 UTC (rev 202226)
+++ trunk/Source/WebCore/ChangeLog 2016-06-20 08:52:10 UTC (rev 202227)
@@ -1,3 +1,26 @@
+2016-06-19 Antti Koivisto <[email protected]>
+
+ Updating class name of a shadow host does not update the style applied by :host()
+ https://bugs.webkit.org/show_bug.cgi?id=158900
+ <rdar://problem/26883707>
+
+ Reviewed by Simon Fraser.
+
+ Test: fast/shadow-dom/shadow-host-style-update.html
+
+ Teach style invalidation optimization code about :host.
+
+ * style/AttributeChangeInvalidation.cpp:
+ (WebCore::Style::mayBeAffectedByHostStyle):
+ (WebCore::Style::AttributeChangeInvalidation::invalidateStyle):
+ * style/ClassChangeInvalidation.cpp:
+ (WebCore::Style::computeClassChange):
+ (WebCore::Style::mayBeAffectedByHostStyle):
+ (WebCore::Style::ClassChangeInvalidation::invalidateStyle):
+ * style/IdChangeInvalidation.cpp:
+ (WebCore::Style::mayBeAffectedByHostStyle):
+ (WebCore::Style::IdChangeInvalidation::invalidateStyle):
+
2016-06-19 Gavin & Ellie Barraclough <[email protected]>
Remove hasStaticPropertyTable (part 5: done!)
Modified: trunk/Source/WebCore/style/AttributeChangeInvalidation.cpp (202226 => 202227)
--- trunk/Source/WebCore/style/AttributeChangeInvalidation.cpp 2016-06-20 07:07:04 UTC (rev 202226)
+++ trunk/Source/WebCore/style/AttributeChangeInvalidation.cpp 2016-06-20 08:52:10 UTC (rev 202227)
@@ -28,6 +28,7 @@
#include "DocumentRuleSets.h"
#include "ElementIterator.h"
+#include "ShadowRoot.h"
#include "StyleInvalidationAnalysis.h"
#include "StyleResolver.h"
@@ -34,6 +35,16 @@
namespace WebCore {
namespace Style {
+static bool mayBeAffectedByHostStyle(ShadowRoot& shadowRoot, bool isHTML, const QualifiedName& attributeName)
+{
+ auto& shadowRuleSets = shadowRoot.styleResolver().ruleSets();
+ if (shadowRuleSets.authorStyle()->hostPseudoClassRules().isEmpty())
+ return false;
+
+ auto& nameSet = isHTML ? shadowRuleSets.features().attributeCanonicalLocalNamesInRules : shadowRuleSets.features().attributeLocalNamesInRules;
+ return nameSet.contains(attributeName.localName().impl());
+}
+
void AttributeChangeInvalidation::invalidateStyle(const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)
{
if (newValue == oldValue)
@@ -43,8 +54,13 @@
bool isHTML = m_element.isHTMLElement();
auto& nameSet = isHTML ? ruleSets.features().attributeCanonicalLocalNamesInRules : ruleSets.features().attributeLocalNamesInRules;
- bool shouldInvalidate = nameSet.contains(attributeName.localName().impl());
- if (!shouldInvalidate)
+ bool mayAffectStyle = nameSet.contains(attributeName.localName().impl());
+
+ auto* shadowRoot = m_element.shadowRoot();
+ if (!mayAffectStyle && shadowRoot && mayBeAffectedByHostStyle(*shadowRoot, isHTML, attributeName))
+ mayAffectStyle = true;
+
+ if (!mayAffectStyle)
return;
if (!isHTML) {
Modified: trunk/Source/WebCore/style/ClassChangeInvalidation.cpp (202226 => 202227)
--- trunk/Source/WebCore/style/ClassChangeInvalidation.cpp 2016-06-20 07:07:04 UTC (rev 202226)
+++ trunk/Source/WebCore/style/ClassChangeInvalidation.cpp 2016-06-20 08:52:10 UTC (rev 202227)
@@ -28,6 +28,7 @@
#include "DocumentRuleSets.h"
#include "ElementChildIterator.h"
+#include "ShadowRoot.h"
#include "SpaceSplitString.h"
#include "StyleInvalidationAnalysis.h"
#include "StyleResolver.h"
@@ -84,15 +85,29 @@
return changedClasses;
}
+static bool mayBeAffectedByHostStyle(ShadowRoot& shadowRoot, AtomicStringImpl* changedClass)
+{
+ auto& shadowRuleSets = shadowRoot.styleResolver().ruleSets();
+ if (shadowRuleSets.authorStyle()->hostPseudoClassRules().isEmpty())
+ return false;
+ return shadowRuleSets.features().classesInRules.contains(changedClass);
+}
+
void ClassChangeInvalidation::invalidateStyle(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses)
{
auto changedClasses = computeClassChange(oldClasses, newClasses);
auto& ruleSets = m_element.styleResolver().ruleSets();
+ auto* shadowRoot = m_element.shadowRoot();
ClassChangeVector changedClassesAffectingStyle;
for (auto* changedClass : changedClasses) {
- if (ruleSets.features().classesInRules.contains(changedClass))
+ bool mayAffectStyle = ruleSets.features().classesInRules.contains(changedClass);
+
+ if (!mayAffectStyle && shadowRoot && mayBeAffectedByHostStyle(*shadowRoot, changedClass))
+ mayAffectStyle = true;
+
+ if (mayAffectStyle)
changedClassesAffectingStyle.append(changedClass);
};
@@ -99,7 +114,7 @@
if (changedClassesAffectingStyle.isEmpty())
return;
- if (m_element.shadowRoot() && ruleSets.authorStyle()->hasShadowPseudoElementRules()) {
+ if (shadowRoot && ruleSets.authorStyle()->hasShadowPseudoElementRules()) {
m_element.setNeedsStyleRecalc(FullStyleChange);
return;
}
Modified: trunk/Source/WebCore/style/IdChangeInvalidation.cpp (202226 => 202227)
--- trunk/Source/WebCore/style/IdChangeInvalidation.cpp 2016-06-20 07:07:04 UTC (rev 202226)
+++ trunk/Source/WebCore/style/IdChangeInvalidation.cpp 2016-06-20 08:52:10 UTC (rev 202227)
@@ -28,11 +28,21 @@
#include "DocumentRuleSets.h"
#include "ElementChildIterator.h"
+#include "ShadowRoot.h"
#include "StyleResolver.h"
namespace WebCore {
namespace Style {
+static bool mayBeAffectedByHostStyle(ShadowRoot& shadowRoot, const AtomicString& changedId)
+{
+ auto& shadowRuleSets = shadowRoot.styleResolver().ruleSets();
+ if (shadowRuleSets.authorStyle()->hostPseudoClassRules().isEmpty())
+ return false;
+
+ return shadowRuleSets.features().idsInRules.contains(changedId.impl());
+}
+
void IdChangeInvalidation::invalidateStyle(const AtomicString& changedId)
{
if (changedId.isEmpty())
@@ -41,6 +51,11 @@
auto& ruleSets = m_element.styleResolver().ruleSets();
bool mayAffectStyle = ruleSets.features().idsInRules.contains(changedId.impl());
+
+ auto* shadowRoot = m_element.shadowRoot();
+ if (!mayAffectStyle && shadowRoot && mayBeAffectedByHostStyle(*shadowRoot, changedId))
+ mayAffectStyle = true;
+
if (!mayAffectStyle)
return;