1 /*
2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21 #include "core/css/MediaQueryList.h"
22
23 #include "core/css/MediaList.h"
24 #include "core/css/MediaQueryEvaluator.h"
25 #include "core/css/MediaQueryListListener.h"
26 #include "core/css/MediaQueryMatcher.h"
27 #include "core/dom/Document.h"
28
29 namespace blink {
30
create(ExecutionContext * context,PassRefPtrWillBeRawPtr<MediaQueryMatcher> matcher,PassRefPtrWillBeRawPtr<MediaQuerySet> media)31 PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryList::create(ExecutionContext* context, PassRefPtrWillBeRawPtr<MediaQueryMatcher> matcher, PassRefPtrWillBeRawPtr<MediaQuerySet> media)
32 {
33 RefPtrWillBeRawPtr<MediaQueryList> list = adoptRefWillBeNoop(new MediaQueryList(context, matcher, media));
34 list->suspendIfNeeded();
35 return list.release();
36 }
37
MediaQueryList(ExecutionContext * context,PassRefPtrWillBeRawPtr<MediaQueryMatcher> matcher,PassRefPtrWillBeRawPtr<MediaQuerySet> media)38 MediaQueryList::MediaQueryList(ExecutionContext* context, PassRefPtrWillBeRawPtr<MediaQueryMatcher> matcher, PassRefPtrWillBeRawPtr<MediaQuerySet> media)
39 : ActiveDOMObject(context)
40 , m_matcher(matcher)
41 , m_media(media)
42 , m_matchesDirty(true)
43 , m_matches(false)
44 {
45 m_matcher->addMediaQueryList(this);
46 updateMatches();
47 }
48
~MediaQueryList()49 MediaQueryList::~MediaQueryList()
50 {
51 #if !ENABLE(OILPAN)
52 m_matcher->removeMediaQueryList(this);
53 #endif
54 }
55
media() const56 String MediaQueryList::media() const
57 {
58 return m_media->mediaText();
59 }
60
addDeprecatedListener(PassRefPtr<EventListener> listener)61 void MediaQueryList::addDeprecatedListener(PassRefPtr<EventListener> listener)
62 {
63 addEventListener(EventTypeNames::change, listener, false);
64 }
65
removeDeprecatedListener(PassRefPtr<EventListener> listener)66 void MediaQueryList::removeDeprecatedListener(PassRefPtr<EventListener> listener)
67 {
68 removeEventListener(EventTypeNames::change, listener, false);
69 }
70
addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener)71 void MediaQueryList::addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener)
72 {
73 if (!listener)
74 return;
75
76 m_listeners.add(listener);
77 }
78
removeListener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener)79 void MediaQueryList::removeListener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener)
80 {
81 if (!listener)
82 return;
83
84 RefPtrWillBeRawPtr<MediaQueryList> protect(this);
85 m_listeners.remove(listener);
86 }
87
hasPendingActivity() const88 bool MediaQueryList::hasPendingActivity() const
89 {
90 return m_listeners.size() || hasEventListeners(EventTypeNames::change);
91 }
92
stop()93 void MediaQueryList::stop()
94 {
95 // m_listeners.clear() can drop the last ref to this MediaQueryList.
96 RefPtrWillBeRawPtr<MediaQueryList> protect(this);
97 m_listeners.clear();
98 removeAllEventListeners();
99 }
100
mediaFeaturesChanged(WillBeHeapVector<RefPtrWillBeMember<MediaQueryListListener>> * listenersToNotify)101 bool MediaQueryList::mediaFeaturesChanged(WillBeHeapVector<RefPtrWillBeMember<MediaQueryListListener> >* listenersToNotify)
102 {
103 m_matchesDirty = true;
104 if (!updateMatches())
105 return false;
106 for (ListenerList::const_iterator it = m_listeners.begin(), end = m_listeners.end(); it != end; ++it) {
107 listenersToNotify->append(*it);
108 }
109 return hasEventListeners(EventTypeNames::change);
110 }
111
updateMatches()112 bool MediaQueryList::updateMatches()
113 {
114 m_matchesDirty = false;
115 if (m_matches != m_matcher->evaluate(m_media.get())) {
116 m_matches = !m_matches;
117 return true;
118 }
119 return false;
120 }
121
matches()122 bool MediaQueryList::matches()
123 {
124 updateMatches();
125 return m_matches;
126 }
127
trace(Visitor * visitor)128 void MediaQueryList::trace(Visitor* visitor)
129 {
130 #if ENABLE(OILPAN)
131 visitor->trace(m_matcher);
132 visitor->trace(m_media);
133 visitor->trace(m_listeners);
134 #endif
135 EventTargetWithInlineData::trace(visitor);
136 }
137
interfaceName() const138 const AtomicString& MediaQueryList::interfaceName() const
139 {
140 return EventTargetNames::MediaQueryList;
141 }
142
executionContext() const143 ExecutionContext* MediaQueryList::executionContext() const
144 {
145 return ActiveDOMObject::executionContext();
146 }
147
148 }
149