Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(436)

Unified Diff: Source/core/css/MediaQueryMatcher.cpp

Issue 348893004: Rework MediaQueryMatcher to batch up listener notification (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: ordering test Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/css/MediaQueryMatcher.h ('k') | Source/core/dom/Document.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/css/MediaQueryMatcher.cpp
diff --git a/Source/core/css/MediaQueryMatcher.cpp b/Source/core/css/MediaQueryMatcher.cpp
index 1821634634a933a8d05996901e702342f4529896..04785f07dccda0e94b15baab3bc2d793ef311e0e 100644
--- a/Source/core/css/MediaQueryMatcher.cpp
+++ b/Source/core/css/MediaQueryMatcher.cpp
@@ -31,37 +31,25 @@
namespace WebCore {
-MediaQueryMatcher::Listener::Listener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener, PassRefPtrWillBeRawPtr<MediaQueryList> query)
- : m_listener(listener)
- , m_query(query)
-{
-}
-
-void MediaQueryMatcher::Listener::evaluate(MediaQueryEvaluator* evaluator)
-{
- if (m_query->evaluate(evaluator))
- m_listener->queryChanged(m_query.get());
-}
-
-void MediaQueryMatcher::Listener::trace(Visitor* visitor)
-{
- visitor->trace(m_listener);
- visitor->trace(m_query);
-}
-
-MediaQueryMatcher::MediaQueryMatcher(Document* document)
- : m_document(document)
- , m_evaluationRound(1)
+MediaQueryMatcher::MediaQueryMatcher(Document& document)
+ : m_document(&document)
{
ASSERT(m_document);
}
DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryMatcher)
-void MediaQueryMatcher::documentDestroyed()
+void MediaQueryMatcher::documentDetached()
{
- m_listeners.clear();
m_document = nullptr;
+
+ // Take a ref to each MediaQuerylist as removing the listeners in documentDetached
+ // could release the last ref and mutate the m_mediaLists.
+ WillBeHeapVector<RefPtrWillBeMember<MediaQueryList> > lists;
+ copyToVector(m_mediaLists, lists);
+
+ for (size_t i = 0; i < lists.size(); ++i)
+ lists[i]->documentDetached();
}
AtomicString MediaQueryMatcher::mediaType() const
@@ -72,7 +60,7 @@ AtomicString MediaQueryMatcher::mediaType() const
return m_document->frame()->view()->mediaType();
}
-PassOwnPtr<MediaQueryEvaluator> MediaQueryMatcher::prepareEvaluator() const
+PassOwnPtr<MediaQueryEvaluator> MediaQueryMatcher::createEvaluator() const
{
if (!m_document || !m_document->frame())
return nullptr;
@@ -85,8 +73,13 @@ bool MediaQueryMatcher::evaluate(const MediaQuerySet* media)
if (!media)
return false;
- OwnPtr<MediaQueryEvaluator> evaluator(prepareEvaluator());
- return evaluator && evaluator->eval(media);
+ if (m_evaluator)
+ return m_evaluator->eval(media);
+
+ if (OwnPtr<MediaQueryEvaluator> evaluator = createEvaluator())
+ return evaluator->eval(media);
Yoav Weiss 2014/06/26 04:43:19 Why aren't you updating m_evaluator here?
+
+ return false;
}
PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const String& query)
@@ -97,57 +90,47 @@ PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const Strin
RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(query);
// Add warning message to inspector whenever dpi/dpcm values are used for "screen" media.
reportMediaQueryWarningIfNeeded(m_document, media.get());
- return MediaQueryList::create(this, media, evaluate(media.get()));
+ return MediaQueryList::create(this, media);
}
-void MediaQueryMatcher::addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener, PassRefPtrWillBeRawPtr<MediaQueryList> query)
+void MediaQueryMatcher::addMediaQueryList(MediaQueryList* query)
{
if (!m_document)
return;
-
- for (size_t i = 0; i < m_listeners.size(); ++i) {
- if (*m_listeners[i]->listener() == *listener && m_listeners[i]->query() == query)
- return;
- }
-
- m_listeners.append(adoptPtrWillBeNoop(new Listener(listener, query)));
+ m_mediaLists.add(query);
}
-void MediaQueryMatcher::removeListener(MediaQueryListListener* listener, MediaQueryList* query)
+void MediaQueryMatcher::removeMediaQueryList(MediaQueryList* query)
{
if (!m_document)
return;
-
- for (size_t i = 0; i < m_listeners.size(); ++i) {
- if (*m_listeners[i]->listener() == *listener && m_listeners[i]->query() == query) {
- m_listeners.remove(i);
- return;
- }
- }
+ m_mediaLists.remove(query);
}
-void MediaQueryMatcher::styleResolverChanged()
+void MediaQueryMatcher::mediaFeaturesChanged()
{
if (!m_document)
return;
- ++m_evaluationRound;
- OwnPtr<MediaQueryEvaluator> evaluator = prepareEvaluator();
- if (!evaluator)
+ // Cache an evaluator so we don't allocate one for each list below.
+ m_evaluator = createEvaluator();
+ if (!m_evaluator)
return;
- for (size_t i = 0; i < m_listeners.size(); ++i)
- m_listeners[i]->evaluate(evaluator.get());
+ WillBeHeapVector<RefPtrWillBeMember<MediaQueryListListener> > listenersToNotify;
+ for (MediaQueryListSet::iterator it = m_mediaLists.begin(); it != m_mediaLists.end(); ++it)
+ (*it)->mediaChanged(&listenersToNotify);
+
+ m_evaluator = nullptr;
Yoav Weiss 2014/06/26 04:43:19 Why create and destroy this evaluator on each chan
esprehn 2014/06/26 05:01:46 The mediaType() is stored in the evaluator and won
+ // FIXME: This should be async! We're running script inside ::layout() or ::updateRenderTree().
+ for (size_t i = 0; i < listenersToNotify.size(); ++i)
+ listenersToNotify[i]->call();
}
void MediaQueryMatcher::trace(Visitor* visitor)
{
visitor->trace(m_document);
- // We don't support tracing of vectors of OwnPtrs (ie. Vector<OwnPtr<Listener> >).
- // Since this is a transitional object we are just ifdef'ing it out when oilpan is not enabled.
-#if ENABLE(OILPAN)
- visitor->trace(m_listeners);
-#endif
+ visitor->trace(m_mediaLists);
}
}
« no previous file with comments | « Source/core/css/MediaQueryMatcher.h ('k') | Source/core/dom/Document.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698