| Index: Source/core/css/MediaQueryList.cpp
|
| diff --git a/Source/core/css/MediaQueryList.cpp b/Source/core/css/MediaQueryList.cpp
|
| index d76b5bbec1599f0b80432c1c55c7184e98a28e46..fd55bd562cd84a0be5ef9fd317acd3f327b092b8 100644
|
| --- a/Source/core/css/MediaQueryList.cpp
|
| +++ b/Source/core/css/MediaQueryList.cpp
|
| @@ -27,21 +27,27 @@
|
|
|
| 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()
|
| +{
|
| +#if !ENABLE(OILPAN)
|
| + m_matcher->removeMediaQueryList(this);
|
| +#endif
|
| +}
|
|
|
| String MediaQueryList::media() const
|
| {
|
| @@ -53,7 +59,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 +68,47 @@ void MediaQueryList::removeListener(PassRefPtrWillBeRawPtr<MediaQueryListListene
|
| if (!listener)
|
| return;
|
|
|
| - m_matcher->removeListener(listener.get(), this);
|
| + RefPtrWillBeRawPtr<MediaQueryList> protect(this);
|
| + listener->clearMediaQueryList();
|
| +
|
| + for (ListenerList::iterator it = m_listeners.begin(), end = m_listeners.end(); it != end; ++it) {
|
| + // 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 (**it == *listener.get()) {
|
| + m_listeners.remove(it);
|
| + 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)
|
| + m_matchesDirty = true;
|
| + if (!updateMatches())
|
| return;
|
| + for (ListenerList::const_iterator it = m_listeners.begin(), end = m_listeners.end(); it != end; ++it) {
|
| + toNotify->append(*it);
|
| + }
|
| +}
|
|
|
| - 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 +116,7 @@ void MediaQueryList::trace(Visitor* visitor)
|
| {
|
| visitor->trace(m_matcher);
|
| visitor->trace(m_media);
|
| + visitor->trace(m_listeners);
|
| }
|
|
|
| }
|
|
|