OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 13 matching lines...) Expand all Loading... | |
24 #include "core/css/MediaQueryEvaluator.h" | 24 #include "core/css/MediaQueryEvaluator.h" |
25 #include "core/css/MediaQueryList.h" | 25 #include "core/css/MediaQueryList.h" |
26 #include "core/css/MediaQueryListListener.h" | 26 #include "core/css/MediaQueryListListener.h" |
27 #include "core/css/resolver/StyleResolver.h" | 27 #include "core/css/resolver/StyleResolver.h" |
28 #include "core/dom/Document.h" | 28 #include "core/dom/Document.h" |
29 #include "core/frame/FrameView.h" | 29 #include "core/frame/FrameView.h" |
30 #include "core/frame/LocalFrame.h" | 30 #include "core/frame/LocalFrame.h" |
31 | 31 |
32 namespace WebCore { | 32 namespace WebCore { |
33 | 33 |
34 MediaQueryMatcher::Listener::Listener(PassRefPtrWillBeRawPtr<MediaQueryListListe ner> listener, PassRefPtrWillBeRawPtr<MediaQueryList> query) | 34 MediaQueryMatcher::MediaQueryMatcher(Document& document) |
35 : m_listener(listener) | 35 : m_document(&document) |
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 { | 36 { |
56 ASSERT(m_document); | 37 ASSERT(m_document); |
57 } | 38 } |
58 | 39 |
59 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryMatcher) | 40 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryMatcher) |
60 | 41 |
61 void MediaQueryMatcher::documentDestroyed() | 42 void MediaQueryMatcher::documentDetached() |
62 { | 43 { |
63 m_listeners.clear(); | |
64 m_document = nullptr; | 44 m_document = nullptr; |
45 | |
46 // Take a ref to each MediaQuerylist as removing the listeners in documentDe tached | |
esprehn
2014/06/26 05:43:24
typo, MediaQueryList
cbiesinger
2014/06/26 20:27:59
Done.
| |
47 // could release the last ref and mutate the m_mediaLists. | |
48 WillBeHeapVector<RefPtrWillBeMember<MediaQueryList> > lists; | |
49 copyToVector(m_mediaLists, lists); | |
50 | |
51 for (size_t i = 0; i < lists.size(); ++i) | |
52 lists[i]->documentDetached(); | |
65 } | 53 } |
66 | 54 |
67 AtomicString MediaQueryMatcher::mediaType() const | 55 AtomicString MediaQueryMatcher::mediaType() const |
68 { | 56 { |
69 if (!m_document || !m_document->frame() || !m_document->frame()->view()) | 57 if (!m_document || !m_document->frame() || !m_document->frame()->view()) |
70 return nullAtom; | 58 return nullAtom; |
71 | 59 |
72 return m_document->frame()->view()->mediaType(); | 60 return m_document->frame()->view()->mediaType(); |
73 } | 61 } |
74 | 62 |
75 PassOwnPtr<MediaQueryEvaluator> MediaQueryMatcher::prepareEvaluator() const | 63 PassOwnPtr<MediaQueryEvaluator> MediaQueryMatcher::createEvaluator() const |
76 { | 64 { |
77 if (!m_document || !m_document->frame()) | 65 if (!m_document || !m_document->frame()) |
78 return nullptr; | 66 return nullptr; |
79 | 67 |
80 return adoptPtr(new MediaQueryEvaluator(mediaType(), m_document->frame())); | 68 return adoptPtr(new MediaQueryEvaluator(mediaType(), m_document->frame())); |
81 } | 69 } |
82 | 70 |
83 bool MediaQueryMatcher::evaluate(const MediaQuerySet* media) | 71 bool MediaQueryMatcher::evaluate(const MediaQuerySet* media) |
84 { | 72 { |
85 if (!media) | 73 if (!media) |
86 return false; | 74 return false; |
87 | 75 |
88 OwnPtr<MediaQueryEvaluator> evaluator(prepareEvaluator()); | 76 if (m_evaluator) |
89 return evaluator && evaluator->eval(media); | 77 return m_evaluator->eval(media); |
78 | |
79 if (OwnPtr<MediaQueryEvaluator> evaluator = createEvaluator()) | |
80 return evaluator->eval(media); | |
81 | |
82 return false; | |
90 } | 83 } |
91 | 84 |
92 PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const Strin g& query) | 85 PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const Strin g& query) |
93 { | 86 { |
94 if (!m_document) | 87 if (!m_document) |
95 return nullptr; | 88 return nullptr; |
96 | 89 |
97 RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(query); | 90 RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(query); |
98 // Add warning message to inspector whenever dpi/dpcm values are used for "s creen" media. | 91 // Add warning message to inspector whenever dpi/dpcm values are used for "s creen" media. |
99 reportMediaQueryWarningIfNeeded(m_document, media.get()); | 92 reportMediaQueryWarningIfNeeded(m_document, media.get()); |
100 return MediaQueryList::create(this, media, evaluate(media.get())); | 93 return MediaQueryList::create(this, media); |
101 } | 94 } |
102 | 95 |
103 void MediaQueryMatcher::addListener(PassRefPtrWillBeRawPtr<MediaQueryListListene r> listener, PassRefPtrWillBeRawPtr<MediaQueryList> query) | 96 void MediaQueryMatcher::addMediaQueryList(MediaQueryList* query) |
97 { | |
98 if (!m_document) | |
99 return; | |
100 m_mediaLists.add(query); | |
101 } | |
102 | |
103 void MediaQueryMatcher::removeMediaQueryList(MediaQueryList* query) | |
104 { | |
105 if (!m_document) | |
106 return; | |
107 m_mediaLists.remove(query); | |
108 } | |
109 | |
110 void MediaQueryMatcher::mediaFeaturesChanged() | |
104 { | 111 { |
105 if (!m_document) | 112 if (!m_document) |
106 return; | 113 return; |
107 | 114 |
108 for (size_t i = 0; i < m_listeners.size(); ++i) { | 115 // Cache an evaluator so we don't allocate one for each list below. |
109 if (*m_listeners[i]->listener() == *listener && m_listeners[i]->query() == query) | 116 m_evaluator = createEvaluator(); |
110 return; | 117 if (!m_evaluator) |
111 } | |
112 | |
113 m_listeners.append(adoptPtrWillBeNoop(new Listener(listener, query))); | |
114 } | |
115 | |
116 void MediaQueryMatcher::removeListener(MediaQueryListListener* listener, MediaQu eryList* query) | |
117 { | |
118 if (!m_document) | |
119 return; | 118 return; |
120 | 119 |
121 for (size_t i = 0; i < m_listeners.size(); ++i) { | 120 WillBeHeapVector<RefPtrWillBeMember<MediaQueryListListener> > listenersToNot ify; |
122 if (*m_listeners[i]->listener() == *listener && m_listeners[i]->query() == query) { | 121 for (MediaQueryListSet::iterator it = m_mediaLists.begin(); it != m_mediaLis ts.end(); ++it) |
123 m_listeners.remove(i); | 122 (*it)->mediaFeaturesChanged(&listenersToNotify); |
124 return; | |
125 } | |
126 } | |
127 } | |
128 | 123 |
129 void MediaQueryMatcher::styleResolverChanged() | 124 m_evaluator = nullptr; |
130 { | 125 // FIXME: This should be async! We're running script inside ::layout() or :: updateRenderTree(). |
131 if (!m_document) | 126 for (size_t i = 0; i < listenersToNotify.size(); ++i) |
132 return; | 127 listenersToNotify[i]->call(); |
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 } | 128 } |
142 | 129 |
143 void MediaQueryMatcher::trace(Visitor* visitor) | 130 void MediaQueryMatcher::trace(Visitor* visitor) |
144 { | 131 { |
145 visitor->trace(m_document); | 132 visitor->trace(m_document); |
146 // We don't support tracing of vectors of OwnPtrs (ie. Vector<OwnPtr<Listene r> >). | 133 visitor->trace(m_mediaLists); |
147 // Since this is a transitional object we are just ifdef'ing it out when oil pan is not enabled. | |
148 #if ENABLE(OILPAN) | |
149 visitor->trace(m_listeners); | |
150 #endif | |
151 } | 134 } |
152 | 135 |
153 } | 136 } |
OLD | NEW |