Diff
Modified: trunk/Source/WebCore/ChangeLog (224494 => 224495)
--- trunk/Source/WebCore/ChangeLog 2017-11-06 17:45:09 UTC (rev 224494)
+++ trunk/Source/WebCore/ChangeLog 2017-11-06 17:45:50 UTC (rev 224495)
@@ -1,3 +1,60 @@
+2017-11-06 Antti Koivisto <[email protected]>
+
+ @media rules ignored in user agent style sheet html.css
+ https://bugs.webkit.org/show_bug.cgi?id=169245
+ <rdar://problem/30885951>
+
+ Reviewed by Darin Adler.
+
+ To support accessibility features, allow non-trivial @media rules in user agent stylesheet.
+
+ This patch creates a special stylesheet consisting of rules with media queries seen on user agent stylesheets.
+ The queries on this sheet are evaluated with the document's media query evaluator.
+
+ No tests as I don't want to add things to UA style just for testing purposes. This will
+ gain coverage when the feature is used.
+
+ * css/CSSDefaultStyleSheets.cpp:
+ (WebCore::CSSDefaultStyleSheets::addToDefaultStyle):
+
+ Add a helper.
+ Build a new stylesheet that consists of complex media rules seen in user agent sheets.
+
+ (WebCore::CSSDefaultStyleSheets::loadFullDefaultStyle):
+ (WebCore::CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement):
+ * css/CSSDefaultStyleSheets.h:
+ * css/DocumentRuleSets.cpp:
+ (WebCore::DocumentRuleSets::userAgentMediaQueryStyle const):
+
+ Rule set constructed from media queries seen on UA sheet.
+
+ (WebCore::DocumentRuleSets::updateUserAgentMediaQueryStyleIfNeeded const):
+
+ Evalute the media queries if needed.
+ Re-evaluate if the rule count of the media query stylesheet increases
+ (this could happen when additional UA style is added).
+
+ (WebCore::DocumentRuleSets::resetUserAgentMediaQueryStyle):
+ (WebCore::DocumentRuleSets::collectFeatures const):
+
+ Collect the features from userAgentMediaQueryStyle.
+
+ * css/DocumentRuleSets.h:
+ (WebCore::DocumentRuleSets::setIsForShadowScope):
+ * css/ElementRuleCollector.cpp:
+ (WebCore::ElementRuleCollector::ElementRuleCollector):
+ (WebCore::ElementRuleCollector::matchUARules):
+
+ Also match rules in userAgentMediaQueryStyle.
+
+ * css/ElementRuleCollector.h:
+ * css/InspectorCSSOMWrappers.cpp:
+ (WebCore::InspectorCSSOMWrappers::collectDocumentWrappers):
+ * css/StyleResolver.cpp:
+ (WebCore::StyleResolver::StyleResolver):
+ * style/StyleScope.cpp:
+ (WebCore::Style::Scope::resolver):
+
2017-11-06 Zalan Bujtas <[email protected]>
[LayoutState cleanup] Move m_layoutState from RenderView to LayoutContext
Modified: trunk/Source/WebCore/css/CSSDefaultStyleSheets.cpp (224494 => 224495)
--- trunk/Source/WebCore/css/CSSDefaultStyleSheets.cpp 2017-11-06 17:45:09 UTC (rev 224494)
+++ trunk/Source/WebCore/css/CSSDefaultStyleSheets.cpp 2017-11-06 17:45:50 UTC (rev 224495)
@@ -69,6 +69,7 @@
StyleSheetContents* CSSDefaultStyleSheets::fullscreenStyleSheet;
StyleSheetContents* CSSDefaultStyleSheets::plugInsStyleSheet;
StyleSheetContents* CSSDefaultStyleSheets::imageControlsStyleSheet;
+StyleSheetContents* CSSDefaultStyleSheets::mediaQueryStyleSheet;
// FIXME: It would be nice to use some mechanism that guarantees this is in sync with the real UA stylesheet.
static const char* simpleUserAgentStyleSheet = "html,body,div{display:block}head{display:none}body{margin:8px}div:focus,span:focus,a:focus{outline:auto 5px -webkit-focus-ring-color}a:any-link{color:-webkit-link;text-decoration:underline}a:any-link:active{color:-webkit-activelink}";
@@ -115,6 +116,30 @@
}
}
+void CSSDefaultStyleSheets::addToDefaultStyle(StyleSheetContents& sheet)
+{
+ defaultStyle->addRulesFromSheet(sheet, screenEval());
+ defaultPrintStyle->addRulesFromSheet(sheet, printEval());
+
+ // Build a stylesheet consisting of non-trivial media queries seen in default style.
+ // Rulesets for these can't be global and need to be built in document context.
+ for (auto& rule : sheet.childRules()) {
+ if (!is<StyleRuleMedia>(*rule))
+ continue;
+ auto& mediaRule = downcast<StyleRuleMedia>(*rule);
+ auto* mediaQuery = mediaRule.mediaQueries();
+ if (!mediaQuery)
+ continue;
+ if (screenEval().evaluate(*mediaQuery, nullptr))
+ continue;
+ if (printEval().evaluate(*mediaQuery, nullptr))
+ continue;
+ mediaQueryStyleSheet->parserAppendRule(mediaRule.copy());
+ }
+
+ ++defaultStyleVersion;
+}
+
void CSSDefaultStyleSheets::loadFullDefaultStyle()
{
if (simpleDefaultStyleSheet) {
@@ -122,21 +147,20 @@
ASSERT(defaultPrintStyle == defaultStyle);
delete defaultStyle;
simpleDefaultStyleSheet->deref();
- defaultStyle = std::make_unique<RuleSet>().release();
- defaultPrintStyle = std::make_unique<RuleSet>().release();
- simpleDefaultStyleSheet = 0;
+ simpleDefaultStyleSheet = nullptr;
} else {
ASSERT(!defaultStyle);
- defaultStyle = std::make_unique<RuleSet>().release();
- defaultPrintStyle = std::make_unique<RuleSet>().release();
defaultQuirksStyle = std::make_unique<RuleSet>().release();
}
+ defaultStyle = std::make_unique<RuleSet>().release();
+ defaultPrintStyle = std::make_unique<RuleSet>().release();
+ mediaQueryStyleSheet = &StyleSheetContents::create(CSSParserContext(UASheetMode)).leakRef();
+
// Strict-mode rules.
String defaultRules = String(htmlUserAgentStyleSheet, sizeof(htmlUserAgentStyleSheet)) + RenderTheme::singleton().extraDefaultStyleSheet();
defaultStyleSheet = parseUASheet(defaultRules);
- defaultStyle->addRulesFromSheet(*defaultStyleSheet, screenEval());
- defaultPrintStyle->addRulesFromSheet(*defaultStyleSheet, printEval());
+ addToDefaultStyle(*defaultStyleSheet);
// Quirks-mode rules.
String quirksRules = String(quirksUserAgentStyleSheet, sizeof(quirksUserAgentStyleSheet)) + RenderTheme::singleton().extraQuirksStyleSheet();
@@ -174,8 +198,7 @@
if (plugInsRules.isEmpty())
plugInsRules = String(plugInsUserAgentStyleSheet, sizeof(plugInsUserAgentStyleSheet));
plugInsStyleSheet = parseUASheet(plugInsRules);
- defaultStyle->addRulesFromSheet(*plugInsStyleSheet, screenEval());
- ++defaultStyleVersion;
+ addToDefaultStyle(*plugInsStyleSheet);
}
}
#if ENABLE(VIDEO)
@@ -185,9 +208,8 @@
if (mediaRules.isEmpty())
mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::singleton().extraMediaControlsStyleSheet();
mediaControlsStyleSheet = parseUASheet(mediaRules);
- defaultStyle->addRulesFromSheet(*mediaControlsStyleSheet, screenEval());
- defaultPrintStyle->addRulesFromSheet(*mediaControlsStyleSheet, printEval());
- ++defaultStyleVersion;
+ addToDefaultStyle(*mediaControlsStyleSheet);
+
}
}
#endif // ENABLE(VIDEO)
@@ -196,9 +218,7 @@
if (!imageControlsStyleSheet) {
String imageControlsRules = RenderTheme::singleton().imageControlsStyleSheet();
imageControlsStyleSheet = parseUASheet(imageControlsRules);
- defaultStyle->addRulesFromSheet(*imageControlsStyleSheet, screenEval());
- defaultPrintStyle->addRulesFromSheet(*imageControlsStyleSheet, printEval());
- ++defaultStyleVersion;
+ addToDefaultStyle(*imageControlsStyleSheet);
}
}
#endif // ENABLE(SERVICE_CONTROLS)
@@ -206,9 +226,7 @@
if (!svgStyleSheet) {
// SVG rules.
svgStyleSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet));
- defaultStyle->addRulesFromSheet(*svgStyleSheet, screenEval());
- defaultPrintStyle->addRulesFromSheet(*svgStyleSheet, printEval());
- ++defaultStyleVersion;
+ addToDefaultStyle(*svgStyleSheet);
}
}
#if ENABLE(MATHML)
@@ -216,9 +234,7 @@
if (!mathMLStyleSheet) {
// MathML rules.
mathMLStyleSheet = parseUASheet(mathmlUserAgentStyleSheet, sizeof(mathmlUserAgentStyleSheet));
- defaultStyle->addRulesFromSheet(*mathMLStyleSheet, screenEval());
- defaultPrintStyle->addRulesFromSheet(*mathMLStyleSheet, printEval());
- ++defaultStyleVersion;
+ addToDefaultStyle(*mathMLStyleSheet);
}
}
#endif // ENABLE(MATHML)
@@ -227,9 +243,7 @@
if (!fullscreenStyleSheet && element.document().webkitIsFullScreen()) {
String fullscreenRules = String(fullscreenUserAgentStyleSheet, sizeof(fullscreenUserAgentStyleSheet)) + RenderTheme::singleton().extraFullScreenStyleSheet();
fullscreenStyleSheet = parseUASheet(fullscreenRules);
- defaultStyle->addRulesFromSheet(*fullscreenStyleSheet, screenEval());
- defaultQuirksStyle->addRulesFromSheet(*fullscreenStyleSheet, screenEval());
- ++defaultStyleVersion;
+ addToDefaultStyle(*fullscreenStyleSheet);
}
#endif // ENABLE(FULLSCREEN_API)
Modified: trunk/Source/WebCore/css/CSSDefaultStyleSheets.h (224494 => 224495)
--- trunk/Source/WebCore/css/CSSDefaultStyleSheets.h 2017-11-06 17:45:09 UTC (rev 224494)
+++ trunk/Source/WebCore/css/CSSDefaultStyleSheets.h 2017-11-06 17:45:50 UTC (rev 224495)
@@ -45,10 +45,15 @@
static StyleSheetContents* plugInsStyleSheet;
static StyleSheetContents* imageControlsStyleSheet;
+ static StyleSheetContents* mediaQueryStyleSheet;
+
+ static void initDefaultStyle(const Element*);
static void ensureDefaultStyleSheetsForElement(const Element&);
+
+private:
static void loadFullDefaultStyle();
static void loadSimpleDefaultStyle();
- static void initDefaultStyle(const Element*);
+ static void addToDefaultStyle(StyleSheetContents&);
};
} // namespace WebCore
Modified: trunk/Source/WebCore/css/DocumentRuleSets.cpp (224494 => 224495)
--- trunk/Source/WebCore/css/DocumentRuleSets.cpp 2017-11-06 17:45:09 UTC (rev 224494)
+++ trunk/Source/WebCore/css/DocumentRuleSets.cpp 2017-11-06 17:45:50 UTC (rev 224495)
@@ -46,6 +46,39 @@
DocumentRuleSets::~DocumentRuleSets() = default;
+RuleSet* DocumentRuleSets::userAgentMediaQueryStyle() const
+{
+ // FIXME: We should have a separate types for document rule sets and shadow tree rule sets.
+ if (m_isForShadowScope)
+ return m_styleResolver.document().styleScope().resolver().ruleSets().userAgentMediaQueryStyle();
+
+ updateUserAgentMediaQueryStyleIfNeeded();
+ return m_userAgentMediaQueryStyle.get();
+}
+
+void DocumentRuleSets::updateUserAgentMediaQueryStyleIfNeeded() const
+{
+ if (!CSSDefaultStyleSheets::mediaQueryStyleSheet)
+ return;
+
+ auto ruleCount = CSSDefaultStyleSheets::mediaQueryStyleSheet->ruleCount();
+ if (m_userAgentMediaQueryStyle && ruleCount == m_userAgentMediaQueryRuleCountOnUpdate)
+ return;
+ m_userAgentMediaQueryRuleCountOnUpdate = ruleCount;
+
+#if !ASSERT_DISABLED
+ bool hadViewportDependentMediaQueries = m_styleResolver.hasViewportDependentMediaQueries();
+#endif
+
+ // Media queries on user agent sheet need to evaluated in document context. They behave like author sheets in this respect.
+ auto& mediaQueryEvaluator = m_styleResolver.mediaQueryEvaluator();
+ m_userAgentMediaQueryStyle = std::make_unique<RuleSet>();
+ m_userAgentMediaQueryStyle->addRulesFromSheet(*CSSDefaultStyleSheets::mediaQueryStyleSheet, mediaQueryEvaluator, &m_styleResolver);
+
+ // Viewport dependent queries are currently too inefficient to allow on UA sheet.
+ ASSERT(!m_styleResolver.hasViewportDependentMediaQueries() || hadViewportDependentMediaQueries);
+}
+
RuleSet* DocumentRuleSets::userStyle() const
{
if (m_usesSharedUserStyle)
@@ -93,6 +126,11 @@
m_authorStyle->disableAutoShrinkToFit();
}
+void DocumentRuleSets::resetUserAgentMediaQueryStyle()
+{
+ m_userAgentMediaQueryStyle = nullptr;
+}
+
void DocumentRuleSets::appendAuthorStyleSheets(const Vector<RefPtr<CSSStyleSheet>>& styleSheets, MediaQueryEvaluator* medium, InspectorCSSOMWrappers& inspectorCSSOMWrappers, StyleResolver* resolver)
{
// This handles sheets added to the end of the stylesheet list only. In other cases the style resolver
@@ -118,6 +156,9 @@
m_features.add(CSSDefaultStyleSheets::defaultStyle->features());
m_defaultStyleVersionOnFeatureCollection = CSSDefaultStyleSheets::defaultStyleVersion;
+ if (auto* userAgentMediaQueryStyle = this->userAgentMediaQueryStyle())
+ m_features.add(userAgentMediaQueryStyle->features());
+
if (m_authorStyle)
m_features.add(m_authorStyle->features());
if (auto* userStyle = this->userStyle())
Modified: trunk/Source/WebCore/css/DocumentRuleSets.h (224494 => 224495)
--- trunk/Source/WebCore/css/DocumentRuleSets.h 2017-11-06 17:45:09 UTC (rev 224494)
+++ trunk/Source/WebCore/css/DocumentRuleSets.h 2017-11-06 17:45:50 UTC (rev 224495)
@@ -44,6 +44,7 @@
~DocumentRuleSets();
bool isAuthorStyleDefined() const { return m_isAuthorStyleDefined; }
+ RuleSet* userAgentMediaQueryStyle() const;
RuleSet& authorStyle() const { return *m_authorStyle.get(); }
RuleSet* userStyle() const;
const RuleFeatureSet& features() const;
@@ -59,6 +60,8 @@
};
const AttributeRules* ancestorAttributeRulesForHTML(const AtomicString&) const;
+ void setIsForShadowScope() { m_isForShadowScope = true; }
+
void setUsesSharedUserStyle(bool b) { m_usesSharedUserStyle = b; }
void initializeUserStyle();
@@ -65,14 +68,19 @@
void resetAuthorStyle();
void appendAuthorStyleSheets(const Vector<RefPtr<CSSStyleSheet>>&, MediaQueryEvaluator*, InspectorCSSOMWrappers&, StyleResolver*);
+ void resetUserAgentMediaQueryStyle();
+
RuleFeatureSet& mutableFeatures();
private:
void collectFeatures() const;
void collectRulesFromUserStyleSheets(const Vector<RefPtr<CSSStyleSheet>>&, RuleSet& userStyle, const MediaQueryEvaluator&, StyleResolver&);
+ void updateUserAgentMediaQueryStyleIfNeeded() const;
+ bool m_isForShadowScope { false };
bool m_isAuthorStyleDefined { false };
std::unique_ptr<RuleSet> m_authorStyle;
+ mutable std::unique_ptr<RuleSet> m_userAgentMediaQueryStyle;
std::unique_ptr<RuleSet> m_userStyle;
bool m_usesSharedUserStyle { false };
@@ -79,6 +87,7 @@
StyleResolver& m_styleResolver;
mutable RuleFeatureSet m_features;
mutable unsigned m_defaultStyleVersionOnFeatureCollection { 0 };
+ mutable unsigned m_userAgentMediaQueryRuleCountOnUpdate { 0 };
mutable std::unique_ptr<RuleSet> m_siblingRuleSet;
mutable std::unique_ptr<RuleSet> m_uncommonAttributeRuleSet;
mutable HashMap<AtomicString, std::unique_ptr<RuleSet>> m_ancestorClassRuleSets;
Modified: trunk/Source/WebCore/css/ElementRuleCollector.cpp (224494 => 224495)
--- trunk/Source/WebCore/css/ElementRuleCollector.cpp 2017-11-06 17:45:09 UTC (rev 224494)
+++ trunk/Source/WebCore/css/ElementRuleCollector.cpp 2017-11-06 17:45:50 UTC (rev 224495)
@@ -83,6 +83,7 @@
: m_element(element)
, m_authorStyle(ruleSets.authorStyle())
, m_userStyle(ruleSets.userStyle())
+ , m_userAgentMediaQueryStyle(ruleSets.userAgentMediaQueryStyle())
, m_selectorFilter(selectorFilter)
{
ASSERT(!m_selectorFilter || m_selectorFilter->parentStackIsConsistent(element.parentNode()));
@@ -320,20 +321,23 @@
m_result.isCacheable = false;
RuleSet* userAgentStyleSheet = m_isPrintStyle
? CSSDefaultStyleSheets::defaultPrintStyle : CSSDefaultStyleSheets::defaultStyle;
- matchUARules(userAgentStyleSheet);
+ matchUARules(*userAgentStyleSheet);
// In quirks mode, we match rules from the quirks user agent sheet.
if (m_element.document().inQuirksMode())
- matchUARules(CSSDefaultStyleSheets::defaultQuirksStyle);
+ matchUARules(*CSSDefaultStyleSheets::defaultQuirksStyle);
+
+ if (m_userAgentMediaQueryStyle)
+ matchUARules(*m_userAgentMediaQueryStyle);
}
-void ElementRuleCollector::matchUARules(RuleSet* rules)
+void ElementRuleCollector::matchUARules(const RuleSet& rules)
{
clearMatchedRules();
m_result.ranges.lastUARule = m_result.matchedProperties().size() - 1;
StyleResolver::RuleRange ruleRange = m_result.ranges.UARuleRange();
- collectMatchingRules(MatchRequest(rules), ruleRange);
+ collectMatchingRules(MatchRequest(&rules), ruleRange);
sortAndTransferMatchedRules();
}
Modified: trunk/Source/WebCore/css/ElementRuleCollector.h (224494 => 224495)
--- trunk/Source/WebCore/css/ElementRuleCollector.h 2017-11-06 17:45:09 UTC (rev 224494)
+++ trunk/Source/WebCore/css/ElementRuleCollector.h 2017-11-06 17:45:50 UTC (rev 224495)
@@ -72,7 +72,7 @@
private:
void addElementStyleProperties(const StyleProperties*, bool isCacheable = true);
- void matchUARules(RuleSet*);
+ void matchUARules(const RuleSet&);
void matchAuthorShadowPseudoElementRules(bool includeEmptyRules, StyleResolver::RuleRange&);
void matchHostPseudoClassRules(bool includeEmptyRules, StyleResolver::RuleRange&);
void matchSlottedPseudoElementRules(bool includeEmptyRules, StyleResolver::RuleRange&);
@@ -92,6 +92,7 @@
const Element& m_element;
const RuleSet& m_authorStyle;
const RuleSet* m_userStyle { nullptr };
+ const RuleSet* m_userAgentMediaQueryStyle { nullptr };
const SelectorFilter* m_selectorFilter { nullptr };
bool m_isPrintStyle { false };
Modified: trunk/Source/WebCore/css/InspectorCSSOMWrappers.cpp (224494 => 224495)
--- trunk/Source/WebCore/css/InspectorCSSOMWrappers.cpp 2017-11-06 17:45:09 UTC (rev 224494)
+++ trunk/Source/WebCore/css/InspectorCSSOMWrappers.cpp 2017-11-06 17:45:50 UTC (rev 224495)
@@ -111,6 +111,7 @@
collectFromStyleSheetContents(CSSDefaultStyleSheets::mediaControlsStyleSheet);
collectFromStyleSheetContents(CSSDefaultStyleSheets::fullscreenStyleSheet);
collectFromStyleSheetContents(CSSDefaultStyleSheets::plugInsStyleSheet);
+ collectFromStyleSheetContents(CSSDefaultStyleSheets::mediaQueryStyleSheet);
collect(extensionStyleSheets.pageUserSheet());
collectFromStyleSheets(extensionStyleSheets.injectedUserStyleSheets());
Modified: trunk/Source/WebCore/css/StyleResolver.cpp (224494 => 224495)
--- trunk/Source/WebCore/css/StyleResolver.cpp 2017-11-06 17:45:09 UTC (rev 224494)
+++ trunk/Source/WebCore/css/StyleResolver.cpp 2017-11-06 17:45:50 UTC (rev 224495)
@@ -231,6 +231,7 @@
m_mediaQueryEvaluator = MediaQueryEvaluator { view->mediaType(), m_document, m_rootDefaultStyle.get() };
m_ruleSets.resetAuthorStyle();
+ m_ruleSets.resetUserAgentMediaQueryStyle();
}
void StyleResolver::addCurrentSVGFontFaceRules()
Modified: trunk/Source/WebCore/style/StyleScope.cpp (224494 => 224495)
--- trunk/Source/WebCore/style/StyleScope.cpp 2017-11-06 17:45:09 UTC (rev 224494)
+++ trunk/Source/WebCore/style/StyleScope.cpp 2017-11-06 17:45:50 UTC (rev 224495)
@@ -102,8 +102,10 @@
if (!m_shadowRoot) {
m_document.fontSelector().buildStarted();
m_resolver->ruleSets().initializeUserStyle();
- } else
+ } else {
+ m_resolver->ruleSets().setIsForShadowScope();
m_resolver->ruleSets().setUsesSharedUserStyle(m_shadowRoot->mode() != ShadowRootMode::UserAgent);
+ }
m_resolver->addCurrentSVGFontFaceRules();
m_resolver->appendAuthorStyleSheets(m_activeStyleSheets);