Simplify media query handling for stylesheets.

Just rebuild the sheets when the viewport changes sizes since that's
super rare in sky right now. This also causes a full document style
recalc, but we'll fix that later too. For now lets make the system
simpler.

R=abarth@chromium.org

Review URL: https://codereview.chromium.org/848483003
This commit is contained in:
Elliott Sprehn 2015-01-20 15:35:25 -08:00
parent 955ede4d3b
commit 7686fb0b8f
10 changed files with 14 additions and 130 deletions

View File

@ -299,7 +299,6 @@ sky_core_files = [
"css/resolver/MatchRequest.h",
"css/resolver/MatchResult.cpp",
"css/resolver/MatchResult.h",
"css/resolver/MediaQueryResult.h",
"css/resolver/ScopedStyleResolver.cpp",
"css/resolver/ScopedStyleResolver.h",
"css/resolver/SharedStyleFinder.cpp",

View File

@ -41,9 +41,9 @@
#include "sky/engine/core/css/CSSToLengthConversionData.h"
#include "sky/engine/core/css/MediaList.h"
#include "sky/engine/core/css/MediaQuery.h"
#include "sky/engine/core/css/MediaQueryExp.h"
#include "sky/engine/core/css/MediaValuesDynamic.h"
#include "sky/engine/core/css/PointerProperties.h"
#include "sky/engine/core/css/resolver/MediaQueryResult.h"
#include "sky/engine/core/dom/NodeRenderStyle.h"
#include "sky/engine/core/frame/FrameHost.h"
#include "sky/engine/core/frame/FrameView.h"
@ -116,7 +116,7 @@ static bool applyRestrictor(MediaQuery::Restrictor r, bool value)
return r == MediaQuery::Not ? !value : value;
}
bool MediaQueryEvaluator::eval(const MediaQuery* query, MediaQueryResultList* viewportDependentMediaQueryResults) const
bool MediaQueryEvaluator::eval(const MediaQuery* query) const
{
if (!mediaTypeMatch(query->mediaType()))
return applyRestrictor(query->restrictor(), false);
@ -125,10 +125,7 @@ bool MediaQueryEvaluator::eval(const MediaQuery* query, MediaQueryResultList* vi
// Iterate through expressions, stop if any of them eval to false (AND semantics).
size_t i = 0;
for (; i < expressions.size(); ++i) {
bool exprResult = eval(expressions.at(i).get());
if (viewportDependentMediaQueryResults && expressions.at(i)->isViewportDependent())
viewportDependentMediaQueryResults->append(adoptRef(new MediaQueryResult(*expressions.at(i), exprResult)));
if (!exprResult)
if (!eval(expressions.at(i).get()))
break;
}
@ -136,7 +133,7 @@ bool MediaQueryEvaluator::eval(const MediaQuery* query, MediaQueryResultList* vi
return applyRestrictor(query->restrictor(), expressions.size() == i);
}
bool MediaQueryEvaluator::eval(const MediaQuerySet* querySet, MediaQueryResultList* viewportDependentMediaQueryResults) const
bool MediaQueryEvaluator::eval(const MediaQuerySet* querySet) const
{
if (!querySet)
return true;
@ -148,7 +145,7 @@ bool MediaQueryEvaluator::eval(const MediaQuerySet* querySet, MediaQueryResultLi
// Iterate over queries, stop if any of them eval to true (OR semantics).
bool result = false;
for (size_t i = 0; i < queries.size() && !result; ++i)
result = eval(queries[i].get(), viewportDependentMediaQueryResults);
result = eval(queries[i].get());
return result;
}

View File

@ -35,13 +35,10 @@ namespace blink {
class LocalFrame;
class MediaQuery;
class MediaQueryExp;
class MediaQueryResult;
class MediaQuerySet;
class MediaValues;
class RenderStyle;
typedef Vector<RefPtr<MediaQueryResult> > MediaQueryResultList;
// Class that evaluates css media queries as defined in
// CSS3 Module "Media Queries" (http://www.w3.org/TR/css3-mediaqueries/)
// Special constructors are needed, if simple media queries are to be
@ -79,10 +76,10 @@ public:
bool mediaTypeMatch(const String& mediaTypeToMatch) const;
// Evaluates a list of media queries.
bool eval(const MediaQuerySet*, MediaQueryResultList* = 0) const;
bool eval(const MediaQuerySet*) const;
// Evaluates media query.
bool eval(const MediaQuery*, MediaQueryResultList*) const;
bool eval(const MediaQuery*) const;
// Evaluates media query subexpression, ie "and (media-feature: value)" part.
bool eval(const MediaQueryExp*) const;

View File

@ -1,55 +0,0 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#ifndef SKY_ENGINE_CORE_CSS_RESOLVER_MEDIAQUERYRESULT_H_
#define SKY_ENGINE_CORE_CSS_RESOLVER_MEDIAQUERYRESULT_H_
#include "sky/engine/core/css/MediaQueryExp.h"
#include "sky/engine/wtf/Noncopyable.h"
#include "sky/engine/wtf/RefCounted.h"
namespace blink {
class MediaQueryResult : public RefCounted<MediaQueryResult> {
WTF_MAKE_NONCOPYABLE(MediaQueryResult); WTF_MAKE_FAST_ALLOCATED;
public:
MediaQueryResult(const MediaQueryExp& expr, bool result)
: m_expression(expr)
, m_result(result)
{
}
const MediaQueryExp* expression() const
{
return &m_expression;
}
bool result() const { return m_result; }
private:
MediaQueryExp m_expression;
bool m_result;
};
}
#endif // SKY_ENGINE_CORE_CSS_RESOLVER_MEDIAQUERYRESULT_H_

View File

@ -46,15 +46,11 @@ ScopedStyleResolver::ScopedStyleResolver(TreeScope& scope)
void ScopedStyleResolver::appendStyleSheet(CSSStyleSheet& sheet)
{
Document& document = m_scope.document();
StyleResolver& styleResolver = document.styleResolver();
MediaQueryEvaluator& medium = styleResolver.medium();
MediaQueryEvaluator medium(m_scope.document().view());
if (sheet.mediaQueries() && !medium.eval(sheet.mediaQueries(), &m_viewportDependentMediaQueryResults))
if (sheet.mediaQueries() && !medium.eval(sheet.mediaQueries()))
return;
styleResolver.addMediaQueryAffectedByViewportChange(m_viewportDependentMediaQueryResults);
const RuleSet& ruleSet = sheet.contents()->ensureRuleSet();
m_features.add(ruleSet.features());
}
@ -77,17 +73,11 @@ void ScopedStyleResolver::updateActiveStyleSheets()
toShadowRoot(root).host()->setNeedsStyleRecalc(SubtreeStyleChange);
m_features.clear();
m_viewportDependentMediaQueryResults.clear();
for (RefPtr<CSSStyleSheet>& sheet : m_authorStyleSheets)
appendStyleSheet(*sheet);
}
const MediaQueryResultList& ScopedStyleResolver::viewportDependentMediaQueryResults() const
{
return m_viewportDependentMediaQueryResults;
}
void ScopedStyleResolver::addStyleSheetCandidateNode(HTMLStyleElement& element)
{
ASSERT(element.inActiveDocument());

View File

@ -66,8 +66,6 @@ public:
void updateActiveStyleSheets();
const MediaQueryResultList& viewportDependentMediaQueryResults() const;
Vector<RefPtr<CSSStyleSheet>>& authorStyleSheets() { return m_authorStyleSheets; }
const Vector<RefPtr<CSSStyleSheet>>& authorStyleSheets() const { return m_authorStyleSheets; }
@ -83,7 +81,6 @@ private:
TreeScope& m_scope;
DocumentOrderedList m_styleSheetCandidateNodes;
Vector<RefPtr<CSSStyleSheet>> m_authorStyleSheets;
MediaQueryResultList m_viewportDependentMediaQueryResults;
RuleFeatureSet m_features;
};

View File

@ -55,7 +55,6 @@
#include "sky/engine/core/css/parser/BisonCSSParser.h"
#include "sky/engine/core/css/resolver/AnimatedStyleBuilder.h"
#include "sky/engine/core/css/resolver/MatchResult.h"
#include "sky/engine/core/css/resolver/MediaQueryResult.h"
#include "sky/engine/core/css/resolver/SharedStyleFinder.h"
#include "sky/engine/core/css/resolver/StyleAdjuster.h"
#include "sky/engine/core/css/resolver/StyleBuilder.h"
@ -118,18 +117,10 @@ static RuleSet& defaultStyles()
StyleResolver::StyleResolver(Document& document)
: m_document(document)
, m_printMediaType(false)
, m_styleResourceLoader(document.fetcher())
, m_styleResolverStatsSequence(0)
, m_accessCount(0)
{
FrameView* view = document.view();
if (view) {
m_medium = adoptPtr(new MediaQueryEvaluator(&view->frame()));
m_printMediaType = equalIgnoringCase(view->mediaType(), MediaTypeNames::print);
} else {
m_medium = adoptPtr(new MediaQueryEvaluator("all"));
}
}
void StyleResolver::addToStyleSharingList(Element& element)
@ -704,23 +695,4 @@ void StyleResolver::applyPropertiesToStyle(const CSSPropertyValue* properties, s
}
}
void StyleResolver::resetMediaQueryAffectedByViewportChange()
{
m_viewportDependentMediaQueryResults.clear();
}
void StyleResolver::addMediaQueryAffectedByViewportChange(const MediaQueryResultList& list)
{
m_viewportDependentMediaQueryResults.appendVector(list);
}
bool StyleResolver::mediaQueryAffectedByViewportChange() const
{
for (unsigned i = 0; i < m_viewportDependentMediaQueryResults.size(); ++i) {
if (m_medium->eval(m_viewportDependentMediaQueryResults[i]->expression()) != m_viewportDependentMediaQueryResults[i]->result())
return true;
}
return false;
}
} // namespace blink

View File

@ -24,7 +24,6 @@
#include "sky/engine/core/css/MediaQueryEvaluator.h"
#include "sky/engine/core/css/resolver/MatchedPropertiesCache.h"
#include "sky/engine/core/css/resolver/MediaQueryResult.h"
#include "sky/engine/core/css/resolver/ScopedStyleResolver.h"
#include "sky/engine/core/css/resolver/StyleResourceLoader.h"
#include "sky/engine/platform/heap/Handle.h"
@ -92,11 +91,6 @@ public:
// FIXME: Rename to reflect the purpose, like didChangeFontSize or something.
void invalidateMatchedPropertiesCache();
MediaQueryEvaluator& medium() const { return *m_medium; }
void resetMediaQueryAffectedByViewportChange();
void addMediaQueryAffectedByViewportChange(const MediaQueryResultList&);
void notifyResizeForViewportUnits();
StyleSharingList& styleSharingList() { return m_styleSharingList; }
@ -149,12 +143,9 @@ private:
MatchedPropertiesCache m_matchedPropertiesCache;
OwnPtr<MediaQueryEvaluator> m_medium;
MediaQueryResultList m_viewportDependentMediaQueryResults;
RawPtr<Document> m_document;
bool m_printMediaType;
StyleResourceLoader m_styleResourceLoader;
StyleSharingList m_styleSharingList;

View File

@ -75,8 +75,6 @@ void StyleEngine::updateActiveStyleSheets()
ASSERT(!m_document->inStyleRecalc());
ASSERT(m_resolver);
m_resolver->resetMediaQueryAffectedByViewportChange();
for (TreeScope* treeScope : m_activeTreeScopes)
treeScope->scopedStyleResolver().updateActiveStyleSheets();

View File

@ -222,15 +222,13 @@ void FrameView::performPreLayoutTasks()
}
Document* document = m_frame->document();
if (wasViewportResized())
if (wasViewportResized()) {
document->notifyResizeForViewportUnits();
// Viewport-dependent media queries may cause us to need completely different style information.
if (document->styleResolver().mediaQueryAffectedByViewportChange()) {
document->styleResolverChanged();
document->mediaQueryAffectingValueChanged();
} else {
document->evaluateMediaQueryList();
// TODO(esprehn): This is way too much work, it rebuilds the entire sheet list
// and does a full document recalc.
document->styleResolverChanged();
}
document->updateRenderTreeIfNeeded();