Diff
Modified: trunk/LayoutTests/ChangeLog (237877 => 237878)
--- trunk/LayoutTests/ChangeLog 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/LayoutTests/ChangeLog 2018-11-06 19:53:13 UTC (rev 237878)
@@ -1,3 +1,16 @@
+2018-11-06 Timothy Hatcher <timo...@apple.com>
+
+ <picture> container doesn't update when prefers-color-scheme media query changes
+ https://bugs.webkit.org/show_bug.cgi?id=190913
+ rdar://problem/45608456
+
+ Reviewed by Dean Jackson.
+
+ * css-dark-mode/prefers-color-scheme-picture-element-expected.txt: Added.
+ * css-dark-mode/prefers-color-scheme-picture-element.html: Added.
+ * platform/mac-highsierra/css-dark-mode/prefers-color-scheme-picture-element-expected.txt: Added.
+ * platform/mac-sierra/css-dark-mode/prefers-color-scheme-picture-element-expected.txt: Added.
+
2018-11-06 Alex Christensen <achristen...@webkit.org>
Fix tests after r237863
Added: trunk/LayoutTests/css-dark-mode/prefers-color-scheme-picture-element-expected.txt (0 => 237878)
--- trunk/LayoutTests/css-dark-mode/prefers-color-scheme-picture-element-expected.txt (rev 0)
+++ trunk/LayoutTests/css-dark-mode/prefers-color-scheme-picture-element-expected.txt 2018-11-06 19:53:13 UTC (rev 237878)
@@ -0,0 +1,6 @@
+
+
+PASS Picture image has the light source selected
+PASS Dark color scheme enabled
+PASS Picture image has the dark source selected
+
Added: trunk/LayoutTests/css-dark-mode/prefers-color-scheme-picture-element.html (0 => 237878)
--- trunk/LayoutTests/css-dark-mode/prefers-color-scheme-picture-element.html (rev 0)
+++ trunk/LayoutTests/css-dark-mode/prefers-color-scheme-picture-element.html 2018-11-06 19:53:13 UTC (rev 237878)
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+
+<!-- webkit-test-runner [ experimental:DarkModeCSSEnabled=true ] -->
+
+<script src=""
+<script src=""
+
+<picture id="test1">
+ <source srcset="dark.png" media="(prefers-color-scheme: dark)">
+ <source srcset="light.png" media="(prefers-color-scheme: light)">
+ <img src=""
+</picture>
+
+<script>
+function test_picture(id, expected) {
+ assert_regexp_match(document.getElementById(id).querySelector("img").currentSrc, new RegExp(`/${expected}$`));
+}
+
+test(function() {
+ // The current image should be the light source.
+ test_picture("test1", "light.png");
+}, "Picture image has the light source selected");
+
+test(function() {
+ if (window.internals)
+ internals.settings.setUseDarkAppearance(true);
+}, "Dark color scheme enabled");
+
+test(function() {
+ // The current image should be the dark source.
+ test_picture("test1", "dark.png");
+}, "Picture image has the dark source selected");
+</script>
Added: trunk/LayoutTests/platform/mac-highsierra/css-dark-mode/prefers-color-scheme-picture-element-expected.txt (0 => 237878)
--- trunk/LayoutTests/platform/mac-highsierra/css-dark-mode/prefers-color-scheme-picture-element-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/mac-highsierra/css-dark-mode/prefers-color-scheme-picture-element-expected.txt 2018-11-06 19:53:13 UTC (rev 237878)
@@ -0,0 +1,6 @@
+
+
+FAIL Picture image has the light source selected assert_regexp_match: expected object "/\/light.png$/" but got "file:///Volumes/Data/EWS/WebKit/LayoutTests/css-dark-mode/error.png"
+PASS Dark color scheme enabled
+FAIL Picture image has the dark source selected assert_regexp_match: expected object "/\/dark.png$/" but got "file:///Volumes/Data/EWS/WebKit/LayoutTests/css-dark-mode/error.png"
+
Added: trunk/LayoutTests/platform/mac-sierra/css-dark-mode/prefers-color-scheme-picture-element-expected.txt (0 => 237878)
--- trunk/LayoutTests/platform/mac-sierra/css-dark-mode/prefers-color-scheme-picture-element-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/mac-sierra/css-dark-mode/prefers-color-scheme-picture-element-expected.txt 2018-11-06 19:53:13 UTC (rev 237878)
@@ -0,0 +1,6 @@
+
+
+FAIL Picture image has the light source selected assert_regexp_match: expected object "/\/light.png$/" but got "file:///Volumes/Data/EWS/WebKit/LayoutTests/css-dark-mode/error.png"
+PASS Dark color scheme enabled
+FAIL Picture image has the dark source selected assert_regexp_match: expected object "/\/dark.png$/" but got "file:///Volumes/Data/EWS/WebKit/LayoutTests/css-dark-mode/error.png"
+
Modified: trunk/Source/WebCore/ChangeLog (237877 => 237878)
--- trunk/Source/WebCore/ChangeLog 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/Source/WebCore/ChangeLog 2018-11-06 19:53:13 UTC (rev 237878)
@@ -1,3 +1,44 @@
+2018-11-06 Timothy Hatcher <timo...@apple.com>
+
+ <picture> container doesn't update when prefers-color-scheme media query changes
+ https://bugs.webkit.org/show_bug.cgi?id=190913
+ rdar://problem/45608456
+
+ Reviewed by Dean Jackson.
+
+ Test: css-dark-mode/prefers-color-scheme-picture-element.html
+
+ * css/MediaQueryEvaluator.cpp:
+ (WebCore::isAppearanceDependent): Added.
+ (WebCore::MediaQueryEvaluator::evaluate const): Keep track of appearanceDependentResults.
+ * css/MediaQueryEvaluator.h:
+ * css/StyleResolver.cpp:
+ (WebCore::StyleResolver::addAppearanceDependentMediaQueryResult): Added.
+ (WebCore::StyleResolver::hasMediaQueriesAffectedByAppearanceChange const): Added.
+ * css/StyleResolver.h:
+ (WebCore::StyleResolver::hasAppearanceDependentMediaQueries const): Added.
+ * dom/Document.cpp:
+ (WebCore::Document::evaluateMediaQueryList): Call checkAppearanceDependentPictures.
+ (WebCore::Document::checkAppearanceDependentPictures): Added.
+ (WebCore::Document::addAppearanceDependentPicture): Added.
+ (WebCore::Document::removeAppearanceDependentPicture): Added.
+ * dom/Document.h:
+ * html/HTMLImageElement.cpp:
+ (WebCore::HTMLImageElement::bestFitSourceFromPictureElement): Call addAppearanceDependentPicture.
+ * html/HTMLPictureElement.cpp:
+ (WebCore::HTMLPictureElement::~HTMLPictureElement): Call removeAppearanceDependentPicture.
+ (WebCore::HTMLPictureElement::didMoveToNewDocument): Ditto.
+ (WebCore::HTMLPictureElement::appearanceChangeAffectedPicture const): Added.
+ * html/HTMLPictureElement.h:
+ * page/Page.cpp:
+ (WebCore::Page::appearanceDidChange): Added.
+ (WebCore::Page::setUseSystemAppearance): Call appearanceDidChange.
+ (WebCore::Page::setUseDarkAppearance): Call appearanceDidChange.
+ * page/Page.h:
+ * style/StyleScope.cpp:
+ (WebCore::Style::Scope::evaluateMediaQueriesForAppearanceChange): Added.
+ * style/StyleScope.h:
+
2018-11-06 Ryan Haddad <ryanhad...@apple.com>
Unreviewed, rolling out r237834.
Modified: trunk/Source/WebCore/css/MediaQueryEvaluator.cpp (237877 => 237878)
--- trunk/Source/WebCore/css/MediaQueryEvaluator.cpp 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/Source/WebCore/css/MediaQueryEvaluator.cpp 2018-11-06 19:53:13 UTC (rev 237878)
@@ -98,6 +98,15 @@
|| mediaFeature == MediaFeatureNames::maxAspectRatio;
}
+static bool isAppearanceDependent(const AtomicString& mediaFeature)
+{
+ return mediaFeature == MediaFeatureNames::prefersDarkInterface
+#if ENABLE(DARK_MODE_CSS)
+ || mediaFeature == MediaFeatureNames::prefersColorScheme
+#endif
+ ;
+}
+
MediaQueryEvaluator::MediaQueryEvaluator(bool mediaFeatureResult)
: m_fallbackResult(mediaFeatureResult)
{
@@ -165,6 +174,8 @@
styleResolver->addViewportDependentMediaQueryResult(expressions[j], expressionResult);
if (styleResolver && isAccessibilitySettingsDependent(expressions[j].mediaFeature()))
styleResolver->addAccessibilitySettingsDependentMediaQueryResult(expressions[j], expressionResult);
+ if (styleResolver && isAppearanceDependent(expressions[j].mediaFeature()))
+ styleResolver->addAppearanceDependentMediaQueryResult(expressions[j], expressionResult);
if (!expressionResult)
break;
}
@@ -179,7 +190,7 @@
return result;
}
-bool MediaQueryEvaluator::evaluate(const MediaQuerySet& querySet, Vector<MediaQueryResult>& results) const
+bool MediaQueryEvaluator::evaluate(const MediaQuerySet& querySet, Vector<MediaQueryResult>& viewportDependentResults, Vector<MediaQueryResult>& appearanceDependentResults) const
{
auto& queries = querySet.queryVector();
if (!queries.size())
@@ -198,7 +209,9 @@
for (; j < expressions.size(); ++j) {
bool expressionResult = evaluate(expressions[j]);
if (isViewportDependent(expressions[j].mediaFeature()))
- results.append({ expressions[j], expressionResult });
+ viewportDependentResults.append({ expressions[j], expressionResult });
+ if (isAppearanceDependent(expressions[j].mediaFeature()))
+ appearanceDependentResults.append({ expressions[j], expressionResult });
if (!expressionResult)
break;
}
Modified: trunk/Source/WebCore/css/MediaQueryEvaluator.h (237877 => 237878)
--- trunk/Source/WebCore/css/MediaQueryEvaluator.h 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/Source/WebCore/css/MediaQueryEvaluator.h 2018-11-06 19:53:13 UTC (rev 237878)
@@ -68,8 +68,8 @@
// Evaluates media query subexpression, ie "and (media-feature: value)" part.
bool evaluate(const MediaQueryExpression&) const;
- // Evaluates a list of media queries and fills in a vector with any viewport-dependent results found.
- bool evaluate(const MediaQuerySet&, Vector<MediaQueryResult>&) const;
+ // Evaluates a list of media queries and fills in vectors with any viewport or dark mode dependent results found.
+ bool evaluate(const MediaQuerySet&, Vector<MediaQueryResult>& viewportDependentResults, Vector<MediaQueryResult>& appearanceDependentResults) const;
static bool mediaAttributeMatches(Document&, const String& attributeValue);
Modified: trunk/Source/WebCore/css/StyleResolver.cpp (237877 => 237878)
--- trunk/Source/WebCore/css/StyleResolver.cpp 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/Source/WebCore/css/StyleResolver.cpp 2018-11-06 19:53:13 UTC (rev 237878)
@@ -1882,6 +1882,21 @@
return false;
}
+void StyleResolver::addAppearanceDependentMediaQueryResult(const MediaQueryExpression& _expression_, bool result)
+{
+ m_appearanceDependentMediaQueryResults.append(MediaQueryResult { _expression_, result });
+}
+
+bool StyleResolver::hasMediaQueriesAffectedByAppearanceChange() const
+{
+ LOG(MediaQueries, "StyleResolver::hasMediaQueriesAffectedByAppearanceChange evaluating queries");
+ for (auto& result : m_appearanceDependentMediaQueryResults) {
+ if (m_mediaQueryEvaluator.evaluate(result._expression_) != result.result)
+ return true;
+ }
+ return false;
+}
+
static FilterOperation::OperationType filterOperationForType(CSSValueID type)
{
switch (type) {
Modified: trunk/Source/WebCore/css/StyleResolver.h (237877 => 237878)
--- trunk/Source/WebCore/css/StyleResolver.h 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/Source/WebCore/css/StyleResolver.h 2018-11-06 19:53:13 UTC (rev 237878)
@@ -209,6 +209,10 @@
bool hasAccessibilitySettingsDependentMediaQueries() const { return !m_accessibilitySettingsDependentMediaQueryResults.isEmpty(); }
bool hasMediaQueriesAffectedByAccessibilitySettingsChange() const;
+ void addAppearanceDependentMediaQueryResult(const MediaQueryExpression&, bool result);
+ bool hasAppearanceDependentMediaQueries() const { return !m_appearanceDependentMediaQueryResults.isEmpty(); }
+ bool hasMediaQueriesAffectedByAppearanceChange() const;
+
void addKeyframeStyle(Ref<StyleRuleKeyframes>&&);
bool usesFirstLineRules() const { return m_ruleSets.features().usesFirstLineRules; }
@@ -509,6 +513,7 @@
Vector<MediaQueryResult> m_viewportDependentMediaQueryResults;
Vector<MediaQueryResult> m_accessibilitySettingsDependentMediaQueryResults;
+ Vector<MediaQueryResult> m_appearanceDependentMediaQueryResults;
#if ENABLE(CSS_DEVICE_ADAPTATION)
RefPtr<ViewportStyleResolver> m_viewportStyleResolver;
Modified: trunk/Source/WebCore/dom/Document.cpp (237877 => 237878)
--- trunk/Source/WebCore/dom/Document.cpp 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/Source/WebCore/dom/Document.cpp 2018-11-06 19:53:13 UTC (rev 237878)
@@ -3809,6 +3809,7 @@
m_mediaQueryMatcher->styleResolverChanged();
checkViewportDependentPictures();
+ checkAppearanceDependentPictures();
}
void Document::checkViewportDependentPictures()
@@ -3823,6 +3824,18 @@
picture->sourcesChanged();
}
+void Document::checkAppearanceDependentPictures()
+{
+ Vector<HTMLPictureElement*, 16> changedPictures;
+ for (auto* picture : m_appearanceDependentPictures) {
+ if (picture->appearanceChangeAffectedPicture())
+ changedPictures.append(picture);
+ }
+
+ for (auto* picture : changedPictures)
+ picture->sourcesChanged();
+}
+
void Document::updateViewportUnitsOnResize()
{
if (!hasStyleWithViewportUnits())
@@ -7580,6 +7593,16 @@
m_viewportDependentPictures.remove(&picture);
}
+void Document::addAppearanceDependentPicture(HTMLPictureElement& picture)
+{
+ m_appearanceDependentPictures.add(&picture);
+}
+
+void Document::removeAppearanceDependentPicture(HTMLPictureElement& picture)
+{
+ m_appearanceDependentPictures.remove(&picture);
+}
+
#if ENABLE(INTERSECTION_OBSERVER)
void Document::addIntersectionObserver(IntersectionObserver& observer)
{
Modified: trunk/Source/WebCore/dom/Document.h (237877 => 237878)
--- trunk/Source/WebCore/dom/Document.h 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/Source/WebCore/dom/Document.h 2018-11-06 19:53:13 UTC (rev 237878)
@@ -1399,6 +1399,9 @@
void addViewportDependentPicture(HTMLPictureElement&);
void removeViewportDependentPicture(HTMLPictureElement&);
+ void addAppearanceDependentPicture(HTMLPictureElement&);
+ void removeAppearanceDependentPicture(HTMLPictureElement&);
+
#if ENABLE(INTERSECTION_OBSERVER)
void addIntersectionObserver(IntersectionObserver&);
void removeIntersectionObserver(IntersectionObserver&);
@@ -1634,6 +1637,7 @@
void didLoadResourceSynchronously() final;
void checkViewportDependentPictures();
+ void checkAppearanceDependentPictures();
#if ENABLE(INTERSECTION_OBSERVER)
void notifyIntersectionObserversTimerFired();
@@ -1828,6 +1832,7 @@
#endif
HashSet<HTMLPictureElement*> m_viewportDependentPictures;
+ HashSet<HTMLPictureElement*> m_appearanceDependentPictures;
#if ENABLE(INTERSECTION_OBSERVER)
Vector<WeakPtr<IntersectionObserver>> m_intersectionObservers;
Modified: trunk/Source/WebCore/html/HTMLImageElement.cpp (237877 => 237878)
--- trunk/Source/WebCore/html/HTMLImageElement.cpp 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/Source/WebCore/html/HTMLImageElement.cpp 2018-11-06 19:53:13 UTC (rev 237878)
@@ -155,8 +155,13 @@
auto picture = makeRefPtr(pictureElement());
if (!picture)
return { };
+
picture->clearViewportDependentResults();
document().removeViewportDependentPicture(*picture);
+
+ picture->clearAppearanceDependentResults();
+ document().removeAppearanceDependentPicture(*picture);
+
for (RefPtr<Node> child = picture->firstChild(); child && child != this; child = child->nextSibling()) {
if (!is<HTMLSourceElement>(*child))
continue;
@@ -179,9 +184,11 @@
MediaQueryEvaluator evaluator { document().printing() ? "print" : "screen", document(), documentElement ? documentElement->computedStyle() : nullptr };
auto* queries = source.parsedMediaAttribute(document());
LOG(MediaQueries, "HTMLImageElement %p bestFitSourceFromPictureElement evaluating media queries", this);
- auto evaluation = !queries || evaluator.evaluate(*queries, picture->viewportDependentResults());
+ auto evaluation = !queries || evaluator.evaluate(*queries, picture->viewportDependentResults(), picture->appearanceDependentResults());
if (picture->hasViewportDependentResults())
document().addViewportDependentPicture(*picture);
+ if (picture->hasAppearanceDependentResults())
+ document().addAppearanceDependentPicture(*picture);
if (!evaluation)
continue;
Modified: trunk/Source/WebCore/html/HTMLPictureElement.cpp (237877 => 237878)
--- trunk/Source/WebCore/html/HTMLPictureElement.cpp 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/Source/WebCore/html/HTMLPictureElement.cpp 2018-11-06 19:53:13 UTC (rev 237878)
@@ -45,11 +45,13 @@
HTMLPictureElement::~HTMLPictureElement()
{
document().removeViewportDependentPicture(*this);
+ document().removeAppearanceDependentPicture(*this);
}
void HTMLPictureElement::didMoveToNewDocument(Document& oldDocument, Document& newDocument)
{
oldDocument.removeViewportDependentPicture(*this);
+ oldDocument.removeAppearanceDependentPicture(*this);
HTMLElement::didMoveToNewDocument(oldDocument, newDocument);
sourcesChanged();
}
@@ -77,6 +79,18 @@
return false;
}
+bool HTMLPictureElement::appearanceChangeAffectedPicture() const
+{
+ auto documentElement = makeRefPtr(document().documentElement());
+ MediaQueryEvaluator evaluator { document().printing() ? "print" : "screen", document(), documentElement ? documentElement->computedStyle() : nullptr };
+ for (auto& result : m_appearanceDependentMediaQueryResults) {
+ LOG(MediaQueries, "HTMLPictureElement %p appearanceChangeAffectedPicture evaluating media queries", this);
+ if (evaluator.evaluate(result._expression_) != result.result)
+ return true;
+ }
+ return false;
+}
+
#if USE(SYSTEM_PREVIEW)
bool HTMLPictureElement::isSystemPreviewImage() const
{
Modified: trunk/Source/WebCore/html/HTMLPictureElement.h (237877 => 237878)
--- trunk/Source/WebCore/html/HTMLPictureElement.h 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/Source/WebCore/html/HTMLPictureElement.h 2018-11-06 19:53:13 UTC (rev 237878)
@@ -42,7 +42,12 @@
bool hasViewportDependentResults() const { return m_viewportDependentMediaQueryResults.size(); }
Vector<MediaQueryResult>& viewportDependentResults() { return m_viewportDependentMediaQueryResults; }
+ void clearAppearanceDependentResults() { m_appearanceDependentMediaQueryResults.clear(); }
+ bool hasAppearanceDependentResults() const { return m_appearanceDependentMediaQueryResults.size(); }
+ Vector<MediaQueryResult>& appearanceDependentResults() { return m_appearanceDependentMediaQueryResults; }
+
bool viewportChangeAffectedPicture() const;
+ bool appearanceChangeAffectedPicture() const;
#if USE(SYSTEM_PREVIEW)
WEBCORE_EXPORT bool isSystemPreviewImage() const;
@@ -54,6 +59,7 @@
void didMoveToNewDocument(Document& oldDocument, Document& newDocument) final;
Vector<MediaQueryResult> m_viewportDependentMediaQueryResults;
+ Vector<MediaQueryResult> m_appearanceDependentMediaQueryResults;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/page/Page.cpp (237877 => 237878)
--- trunk/Source/WebCore/page/Page.cpp 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/Source/WebCore/page/Page.cpp 2018-11-06 19:53:13 UTC (rev 237878)
@@ -2455,6 +2455,18 @@
}
}
+void Page::appearanceDidChange()
+{
+ for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ auto* document = frame->document();
+ if (!document)
+ continue;
+
+ document->styleScope().evaluateMediaQueriesForAppearanceChange();
+ document->evaluateMediaQueryList();
+ }
+}
+
void Page::setUnobscuredSafeAreaInsets(const FloatBoxExtent& insets)
{
if (m_unobscuredSafeAreaInsets == insets)
@@ -2476,7 +2488,7 @@
m_useSystemAppearance = value;
- updateStyleAfterChangeInEnvironment();
+ appearanceDidChange();
for (auto* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
auto* document = frame->document();
@@ -2496,7 +2508,7 @@
m_useDarkAppearance = value;
- updateStyleAfterChangeInEnvironment();
+ appearanceDidChange();
}
bool Page::useDarkAppearance() const
Modified: trunk/Source/WebCore/page/Page.h (237877 => 237878)
--- trunk/Source/WebCore/page/Page.h 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/Source/WebCore/page/Page.h 2018-11-06 19:53:13 UTC (rev 237878)
@@ -382,6 +382,7 @@
ScrollElasticity horizontalScrollElasticity() const { return static_cast<ScrollElasticity>(m_horizontalScrollElasticity); }
WEBCORE_EXPORT void accessibilitySettingsDidChange();
+ WEBCORE_EXPORT void appearanceDidChange();
// Page and FrameView both store a Pagination value. Page::pagination() is set only by API,
// and FrameView::pagination() is set only by CSS. Page::pagination() will affect all
Modified: trunk/Source/WebCore/style/StyleScope.cpp (237877 => 237878)
--- trunk/Source/WebCore/style/StyleScope.cpp 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/Source/WebCore/style/StyleScope.cpp 2018-11-06 19:53:13 UTC (rev 237878)
@@ -632,6 +632,13 @@
});
}
+void Scope::evaluateMediaQueriesForAppearanceChange()
+{
+ evaluateMediaQueries([] (StyleResolver& resolver) {
+ return resolver.hasMediaQueriesAffectedByAppearanceChange();
+ });
+}
+
template <typename TestFunction>
void Scope::evaluateMediaQueries(TestFunction&& testFunction)
{
Modified: trunk/Source/WebCore/style/StyleScope.h (237877 => 237878)
--- trunk/Source/WebCore/style/StyleScope.h 2018-11-06 19:19:06 UTC (rev 237877)
+++ trunk/Source/WebCore/style/StyleScope.h 2018-11-06 19:53:13 UTC (rev 237878)
@@ -97,6 +97,7 @@
void evaluateMediaQueriesForViewportChange();
void evaluateMediaQueriesForAccessibilitySettingsChange();
+ void evaluateMediaQueriesForAppearanceChange();
// This is called when some stylesheet becomes newly enabled or disabled.
void didChangeActiveStyleSheetCandidates();