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

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

Issue 348893004: Rework MediaQueryMatcher to batch up listener notification (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: MediaQueryList constructor needs to call updateMatches to avoid "fake" transitions from "unknown st… 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
Index: Source/core/css/MediaQueryList.cpp
diff --git a/Source/core/css/MediaQueryList.cpp b/Source/core/css/MediaQueryList.cpp
index d76b5bbec1599f0b80432c1c55c7184e98a28e46..3a1b9345b3907ea8ec6bb7837f78ea56d0eff2f4 100644
--- a/Source/core/css/MediaQueryList.cpp
+++ b/Source/core/css/MediaQueryList.cpp
@@ -27,21 +27,26 @@
namespace WebCore {
-PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryList::create(PassRefPtrWillBeRawPtr<MediaQueryMatcher> vector, PassRefPtrWillBeRawPtr<MediaQuerySet> media, bool matches)
+PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryList::create(PassRefPtrWillBeRawPtr<MediaQueryMatcher> matcher, PassRefPtrWillBeRawPtr<MediaQuerySet> media)
{
- return adoptRefWillBeNoop(new MediaQueryList(vector, media, matches));
+ return adoptRefWillBeNoop(new MediaQueryList(matcher, media));
}
-MediaQueryList::MediaQueryList(PassRefPtrWillBeRawPtr<MediaQueryMatcher> vector, PassRefPtrWillBeRawPtr<MediaQuerySet> media, bool matches)
- : m_matcher(vector)
+MediaQueryList::MediaQueryList(PassRefPtrWillBeRawPtr<MediaQueryMatcher> matcher, PassRefPtrWillBeRawPtr<MediaQuerySet> media)
+ : m_matcher(matcher)
, m_media(media)
- , m_evaluationRound(m_matcher->evaluationRound())
- , m_changeRound(m_evaluationRound - 1) // m_evaluationRound and m_changeRound initial values must be different.
- , m_matches(matches)
+ , m_matchesDirty(true)
+ , m_matches(false)
{
+ m_matcher->addMediaQueryList(this);
+ updateMatches();
}
-DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryList)
+MediaQueryList::~MediaQueryList()
+{
+ // FIXME: Figure out how to deal with this in oilpan.
Mads Ager (chromium) 2014/06/26 06:06:22 Right, this will not work for the oilpan build sin
cbiesinger 2014/06/26 20:27:59 Done.
+ m_matcher->removeMediaQueryList(this);
+}
String MediaQueryList::media() const
{
@@ -53,7 +58,8 @@ void MediaQueryList::addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener>
if (!listener)
return;
- m_matcher->addListener(listener, this);
+ listener->setMediaQueryList(this);
+ m_listeners.add(listener);
}
void MediaQueryList::removeListener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener)
@@ -61,31 +67,47 @@ void MediaQueryList::removeListener(PassRefPtrWillBeRawPtr<MediaQueryListListene
if (!listener)
return;
- m_matcher->removeListener(listener.get(), this);
+ RefPtrWillBeRawPtr<MediaQueryList> protect(this);
+ listener->clearMediaQueryList();
+
+ for (ListenerList::iterator i = m_listeners.begin(), end = m_listeners.end(); i != end; ++i) {
+ // We can't just use m_listeners.remove() here, because we get a new wrapper for the
+ // listener callback every time. We have to use MediaQueryListListener::operator==.
+ if (**i == *listener.get()) {
+ m_listeners.remove(i);
+ break;
+ }
+ }
}
-bool MediaQueryList::evaluate(MediaQueryEvaluator* evaluator)
+void MediaQueryList::documentDetached()
{
- if (m_evaluationRound != m_matcher->evaluationRound() && evaluator)
- setMatches(evaluator->eval(m_media.get()));
- return m_changeRound == m_matcher->evaluationRound();
+ m_listeners.clear();
}
-void MediaQueryList::setMatches(bool newValue)
+void MediaQueryList::mediaFeaturesChanged(WillBeHeapVector<RefPtrWillBeMember<MediaQueryListListener> >* toNotify)
{
- m_evaluationRound = m_matcher->evaluationRound();
-
- if (newValue == m_matches)
- return;
+ m_matchesDirty = true;
+ if (updateMatches()) {
esprehn 2014/06/26 05:43:24 early return. if (!updateMatches()) return; for
cbiesinger 2014/06/26 20:27:59 Done.
+ for (ListenerList::const_iterator i = m_listeners.begin(), end = m_listeners.end(); i != end; ++i) {
+ toNotify->append(*i);
+ }
+ }
+}
- m_matches = newValue;
- m_changeRound = m_evaluationRound;
+bool MediaQueryList::updateMatches()
+{
+ m_matchesDirty = false;
+ if (m_matches != m_matcher->evaluate(m_media.get())) {
+ m_matches = !m_matches;
+ return true;
+ }
+ return false;
}
bool MediaQueryList::matches()
{
- if (m_evaluationRound != m_matcher->evaluationRound())
- setMatches(m_matcher->evaluate(m_media.get()));
+ updateMatches();
return m_matches;
}
@@ -93,6 +115,7 @@ void MediaQueryList::trace(Visitor* visitor)
{
visitor->trace(m_matcher);
visitor->trace(m_media);
+ visitor->trace(m_listeners);
}
}

Powered by Google App Engine
This is Rietveld 408576698