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 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 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 49 MediaQueryList::~MediaQueryList() 50 { 51 #if !ENABLE(OILPAN) 52 m_matcher->removeMediaQueryList(this); 53 #endif 54 } 55 56 String MediaQueryList::media() const 57 { 58 return m_media->mediaText(); 59 } 60 61 void MediaQueryList::addDeprecatedListener(PassRefPtr<EventListener> listener) 62 { 63 addEventListener(EventTypeNames::change, listener, false); 64 } 65 66 void MediaQueryList::removeDeprecatedListener(PassRefPtr<EventListener> listener) 67 { 68 removeEventListener(EventTypeNames::change, listener, false); 69 } 70 71 void MediaQueryList::addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener) 72 { 73 if (!listener) 74 return; 75 76 m_listeners.add(listener); 77 } 78 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 88 bool MediaQueryList::hasPendingActivity() const 89 { 90 return m_listeners.size() || hasEventListeners(EventTypeNames::change); 91 } 92 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 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 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 122 bool MediaQueryList::matches() 123 { 124 updateMatches(); 125 return m_matches; 126 } 127 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 138 const AtomicString& MediaQueryList::interfaceName() const 139 { 140 return EventTargetNames::MediaQueryList; 141 } 142 143 ExecutionContext* MediaQueryList::executionContext() const 144 { 145 return ActiveDOMObject::executionContext(); 146 } 147 148 } 149