Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / MediaQueryMatcher.cpp
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/MediaQueryMatcher.h"
22
23 #include "core/css/MediaList.h"
24 #include "core/css/MediaQueryEvaluator.h"
25 #include "core/css/MediaQueryList.h"
26 #include "core/css/MediaQueryListListener.h"
27 #include "core/css/resolver/StyleResolver.h"
28 #include "core/dom/Document.h"
29 #include "core/frame/FrameView.h"
30 #include "core/frame/LocalFrame.h"
31
32 namespace WebCore {
33
34 MediaQueryMatcher::Listener::Listener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener, PassRefPtrWillBeRawPtr<MediaQueryList> query)
35     : m_listener(listener)
36     , m_query(query)
37 {
38 }
39
40 void MediaQueryMatcher::Listener::evaluate(MediaQueryEvaluator* evaluator)
41 {
42     if (m_query->evaluate(evaluator))
43         m_listener->queryChanged(m_query.get());
44 }
45
46 void MediaQueryMatcher::Listener::trace(Visitor* visitor)
47 {
48     visitor->trace(m_listener);
49     visitor->trace(m_query);
50 }
51
52 MediaQueryMatcher::MediaQueryMatcher(Document* document)
53     : m_document(document)
54     , m_evaluationRound(1)
55 {
56     ASSERT(m_document);
57 }
58
59 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryMatcher)
60
61 void MediaQueryMatcher::documentDestroyed()
62 {
63     m_listeners.clear();
64     m_document = 0;
65 }
66
67 AtomicString MediaQueryMatcher::mediaType() const
68 {
69     if (!m_document || !m_document->frame() || !m_document->frame()->view())
70         return nullAtom;
71
72     return m_document->frame()->view()->mediaType();
73 }
74
75 PassOwnPtr<MediaQueryEvaluator> MediaQueryMatcher::prepareEvaluator() const
76 {
77     if (!m_document || !m_document->frame())
78         return nullptr;
79
80     return adoptPtr(new MediaQueryEvaluator(mediaType(), m_document->frame()));
81 }
82
83 bool MediaQueryMatcher::evaluate(const MediaQuerySet* media)
84 {
85     if (!media)
86         return false;
87
88     OwnPtr<MediaQueryEvaluator> evaluator(prepareEvaluator());
89     return evaluator && evaluator->eval(media);
90 }
91
92 PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const String& query)
93 {
94     if (!m_document)
95         return nullptr;
96
97     RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(query);
98     // Add warning message to inspector whenever dpi/dpcm values are used for "screen" media.
99     reportMediaQueryWarningIfNeeded(m_document, media.get());
100     return MediaQueryList::create(this, media, evaluate(media.get()));
101 }
102
103 void MediaQueryMatcher::addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener, PassRefPtrWillBeRawPtr<MediaQueryList> query)
104 {
105     if (!m_document)
106         return;
107
108     for (size_t i = 0; i < m_listeners.size(); ++i) {
109         if (*m_listeners[i]->listener() == *listener && m_listeners[i]->query() == query)
110             return;
111     }
112
113     m_listeners.append(adoptPtrWillBeNoop(new Listener(listener, query)));
114 }
115
116 void MediaQueryMatcher::removeListener(MediaQueryListListener* listener, MediaQueryList* query)
117 {
118     if (!m_document)
119         return;
120
121     for (size_t i = 0; i < m_listeners.size(); ++i) {
122         if (*m_listeners[i]->listener() == *listener && m_listeners[i]->query() == query) {
123             m_listeners.remove(i);
124             return;
125         }
126     }
127 }
128
129 void MediaQueryMatcher::styleResolverChanged()
130 {
131     if (!m_document)
132         return;
133
134     ++m_evaluationRound;
135     OwnPtr<MediaQueryEvaluator> evaluator = prepareEvaluator();
136     if (!evaluator)
137         return;
138
139     for (size_t i = 0; i < m_listeners.size(); ++i)
140         m_listeners[i]->evaluate(evaluator.get());
141 }
142
143 void MediaQueryMatcher::trace(Visitor* visitor)
144 {
145     // We don't support tracing of vectors of OwnPtrs (ie. Vector<OwnPtr<Listener> >).
146     // Since this is a transitional object we are just ifdef'ing it out when oilpan is not enabled.
147 #if ENABLE(OILPAN)
148     visitor->trace(m_listeners);
149 #endif
150 }
151
152 }